home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / appli / ui.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-31  |  69.0 KB  |  2,508 lines  |  [TEXT/MPS ]

  1. #include <Controls.h>
  2. #include <Desk.h>
  3. #include <Dialogs.h>
  4. #include <DiskInit.h>
  5. #include <Errors.h>
  6. #include <Events.h>
  7. #include <Files.h>
  8. #include <Fonts.h>
  9. #include <Memory.h>
  10. #include <Menus.h>
  11. #include <OSEvents.h>
  12. #include <OSUtils.h>
  13. #include <Packages.h>
  14. #include <Palettes.h>
  15. #include <QuickDraw.h>
  16. #include <Resources.h>
  17. #include <Scrap.h>
  18. #include <Script.h>
  19. #include <SegLoad.h>
  20. #include <Signal.h>
  21. #include <StandardFile.h>
  22. #include <StdIO.h>
  23. #include <StdLib.h>
  24. #include <SysEqu.h>
  25. #include <TextEdit.h>
  26. #include <TextEdit.h>
  27. #include <ToolUtils.h>
  28. #include <Traps.h>
  29. #include <Types.h>
  30. #include <Values.h>
  31. #include <Windows.h>
  32.  
  33.  
  34. #include "ui.h"
  35. #include "camlmenus.h"
  36.  
  37. #define rMenuBar        128        /* Liste des menus                */
  38.  
  39. #define mApple            128        /* Menu Pomme                    */
  40. #define iAbout            1        /* item 'A propos...'            */
  41.  
  42. #define mFile            129        /* Menu File                    */
  43. #define iOpen             1        /* item Open...            =O        */
  44. #define iClose             3        /* item Close            =W        */
  45. #define iSave             4        /* item Save            =S        */
  46. #define iInclude        6
  47. #define iCompile        7
  48. #define iLoad           8
  49. #define iLoadObject        9
  50. #define iQuit             11        /* item Quit            =Q        */
  51.  
  52. #define mEdit             130        /* Menu Edit                    */
  53. #define iUndo             1        /* item Undo            =Z        */
  54. #define iCut             3        /* item Cut                =X        */
  55. #define iCopy             4        /* item Copy            =C        */
  56. #define iPaste            5        /* item Paste            =V        */
  57. #define iClear             6        /* item Clear                    */
  58. #define iSelAll            8        /* item Select All        =A        */
  59.  
  60. #define mCaml            131        /* Menu History                    */
  61. #define iShowGraph        1        /* Show Graphic            =G        */
  62. #define iShowHist        2        /* Show History            =H        */
  63. #define iPrevEnt        3        /* Previous Entry        =P        */
  64. #define iNextEnt        4        /* Next Entry            =N        */
  65. #define iInterrupt        6        /* Interrupt Caml        =.        */
  66. #define iGC             7
  67. #define iPref            9        /* item Preferences                */
  68.  
  69. #define rErrorList         128        /* Liste des messages d'erreur                        */
  70. #define eNoMemory         1        /* Not enough memory                                */
  71. #define eNoRessource     2        /* The needed resource cannot be load                */
  72. #define eNoTextEdit     3        /* TextEdit cannot be used                            */
  73. #define eNoScrap         4        /* The clipboard is unusable                        */
  74. #define eNoScrapPut     5        /* Impossible to write on the clipboard                */
  75. #define eNoScrapGet     6        /* Impossible to read the clipborad                    */
  76. #define eNoMoreText     7        /* This window cannot get more memory                */
  77. #define eWrongMachine     8        /* Caml Light cannot run on this type of Macintosh    */
  78. #define eNoMoreHistory    9        /* No more room in the history                        */
  79. #define eTooMuchChars    10        /* Too much characters in this window                */
  80. #define eCannotCreate    11        /* Cannot create the file. */
  81. #define eCannotWrite    12        /* Cannot write to the file. */
  82. #define eCannotReplace    13        /* Cannot replace the file. */
  83.  
  84. #define rErrorAlert        128        /* alerte                        */
  85. #define rAboutAlert        129        /* alerte pour A propos...        */
  86. #define rSizeAlert        130        /* alerte preferences texte        */
  87.  
  88. #define rPreferences    128        /* dialogue Preferences            */
  89. #define iOK                1        /* item OK                        */
  90. #define iCancel            2        /* item Cancel                    */
  91. #define iDefault        3        /* item Default                    */
  92.  
  93. #define iFirstControl    4        /* The first control is Return    */
  94. #define iReturn            4        /* item Return = Send To Caml    */
  95. #define iEnter            5        /* item Enter = Send To Caml    */
  96. #define iShHistory        6        /* item Show History            */
  97. #define iAutoScroll        7        /* item Auto scroll Output        */
  98. #define iSavePos        8        /* item Save position of window    */
  99. #define iPrMaxSize        9        /* item Printer Max Size        */
  100. #define iPrFlushSize    10        /* item Printer Flush Size        */
  101. #define iHiMaxSize        11        /* item History Max Size        */
  102. #define iHiFlushSize    12        /* item History Flush Size        */
  103. #define iTextCreator    13
  104. #define iLastControl    13        /* The last control is TextCreator */
  105.  
  106. #define rPREF            128        /* resource preferences            */
  107.  
  108. #define rWindow            128        /* fenetre de donnees            */
  109.  
  110. #define rWTitle            129        /* Liste des noms de fenetres    */
  111. #define tOutput            1        /* Nom fenetre Output            */
  112. #define tInput            2        /* Nom fenetre Input            */
  113. #define tHistory        3        /* Nom fenetre History            */
  114. #define tGraphic        4        /* Nom fenetre Graphic            */
  115.  
  116. #define rMiscStr        130
  117. #define sSaveOutput        1
  118. #define sSaveHistory    2
  119. #define sUntitled        3
  120. #define sHistory_ml        4
  121.  
  122. #define Visible            0xFF    /* controle visible                */
  123. #define inVisible        0        /* controle invisible            */
  124. #define MARGINDRAG        4        /* marge limite pour drag        */
  125. #define SBWIDTH            16        /* largeur scroll bar            */
  126. #define WNDMARG            25        /* marge entre les fenetres        */
  127. #define WMINSIZE        70        /* minimum taille d'une fenetre    */
  128. #define WNORMWIDTH        500        /* largeur normale 80 colonnes    */
  129. #define TXTMARG            4        /* marge d'une fenetre texte    */
  130. #define WRAP            1        /* passage a la ligne sans CR    */
  131. #define Enter            0x03    /* code ASCII touche Enter        */
  132. #define CReturn            0x0D    /* code ASCII touche Return        */
  133. #define DelKey            0x7F    /* code ASCII touche Del        */
  134. #define TEWSIZE         200        /* taille fenetre text en chars    */
  135. #define MAXCHAR            2000    /* maximum chars / ligne output    */
  136. #define CHARWIDTH        6        /* largeur des caracteres        */
  137. #define NSCHAR            5        /* nombre de chars a scroller    */
  138. #define NSPIXEL            10        /* nombre de pixels a scroller    */
  139. #define VSCROLLVIS        1        /* lignes visibles apres scroll    */
  140. #define HSCROLLVIS        5        /* chars visibles apres scroll    */
  141. #define TEBLOCK            1024    /* taille block memoire texte    */
  142. #define BUFBLOCK        1024    /* taille block liste buffer    */
  143. #define FONTSIZE        9        /* taille des caracteres        */
  144. #define Ttop            -1        /* souris au-dessus du texte    */
  145. #define Tbottom            -2        /* souris en-dessous du texte    */
  146. #define Tleft            -3        /* souris a gauche du texte        */
  147. #define Tright            -4        /* souris a droite du texte        */
  148. #define Version            1        /* pour SysEnviron                */
  149. #define nCR                2        /* nombre de cr entre buffers    */
  150. #define MAXSIZE            50        /* taille max output par defaut    */
  151. #define FLUSHSIZE        10        /* taille text purge par defaut    */
  152. #define DIX                50        /* abscisse dialogue DiskEvt    */
  153. #define DIY                50        /* ordonnee dialog DiskEvt        */
  154. #define SIZEX            480        /* taille par defaut CamlGraph    */
  155. #define SIZEY            280        /* taille par defaut CamlGraph    */
  156.  
  157. #define WindowType(window)        ((((WindowPeek) (window))->windowKind == userKind) ? ((dataPeek) (window))->type : 0)
  158. #define isTEWindow(window)        (WindowType(window) == tInput)
  159. #define isTextWindow(window)    (((window) == CAMLPrinter) || ((window) == CAMLHistory))
  160. #define isGraphWindow(window)    ((window) == CAMLGraph)
  161. #define ctl(i)                    (control[(i) - iFirstControl])
  162. #define    gp                        ((graphPeek) CAMLOffScreen)
  163.  
  164. typedef struct data *dataPeek;
  165.  
  166. typedef struct data {
  167.     WindowRecord window;
  168.     ControlHandle vSBar;
  169.     ControlHandle hSBar;
  170.     short type;                /* type de la fenetre : contient en fait l'index de son titre    */
  171.     long h;                    /* handle pour TEHandle par exemple...                            */
  172.     dataPeek prevWindow;
  173.     dataPeek nextWindow;
  174. } dataRecord;
  175.  
  176. typedef struct LRect {
  177.     long top;
  178.     short left;
  179.     short right;
  180. } LRect;
  181.  
  182. typedef long **bufHandle;
  183.  
  184. typedef struct text {
  185.     LRect destRect;
  186.     Rect viewRect;
  187.     short lineHeight;
  188.     short ascent;
  189.     short width;
  190.     long last_line_length;
  191.     long selStart;
  192.     long selEnd;
  193.     long teLength;
  194.     long firstLine;
  195.     Handle hText;
  196.     long nLines;
  197.     bufHandle buffer;
  198. } textRecord, *textPtr, **textHandle;
  199.  
  200. typedef struct graph {
  201.     GrafPort offScreen;
  202.     Rect destRect;
  203.     Rect viewRect;
  204.     Rect destRectZoom;
  205. } graphRecord, *graphPeek;
  206.  
  207. typedef struct Preferences {
  208.     long magic_number;
  209.     Boolean Return;            /* si true, Return envoie le texte a Caml        */
  210.     Boolean ShowHist;
  211.     Boolean AutoScroll;
  212.     Boolean SavePos;
  213.     Rect LiWindowRect;
  214.     Rect PrWindowRect;
  215.     long PrMaxSize;    
  216.     long PrFlushSize;
  217.     Rect HiWindowRect;
  218.     long HiMaxSize;
  219.     long HiFlushSize;
  220.     Rect GrWindowRect;
  221.     char text_creator [4];
  222. } *PrefPtr;
  223. typedef PrefPtr *PrefHandle;
  224.  
  225. PrefPtr Pref = nil;
  226. int color_qd = 0;
  227. dataPeek WList;                /* pointeur sur la premiere fenetre de la liste    */
  228. Boolean inForeground;
  229. Boolean WNEAvailable;
  230. WindowPtr CAMLInput = nil;
  231. WindowPtr CAMLPrinter = nil;
  232. WindowPtr CAMLHistory = nil;
  233. WindowPtr CAMLGraph = nil;
  234. WindowPtr CAMLOffScreen = nil;
  235. GDHandle CAMLGDevice = nil;
  236. int max_depth;
  237. long indexBuffer;
  238. ClikLoopProcPtr oldClikLoop;
  239. int wait_graph_move = 0;
  240. #define N_graph_events 20
  241. EventRecord graph_event_queue [N_graph_events];
  242. int graph_event_head = 0;
  243. int graph_event_tail = 0;
  244. int reading = 0;
  245.  
  246. RgnHandle FixCursor(void);
  247. void push_graph_event ();
  248. void DoEvent(EventRecord *event);
  249. void DoMouseDown(EventRecord *event);
  250. void DoClickContent(WindowPtr window, EventRecord *event);
  251. void SelectText(textHandle t, Point mouse, short extend);
  252. long MouseToText(textPtr t, Point mouse);
  253. pascal void DoClickTESBar(ControlHandle control, short part);
  254. pascal void DoClickTextSBar(ControlHandle control, short part);
  255. pascal void DoClickGraphSBar(ControlHandle control, short part);
  256. void AdjustMenus(WindowPtr window);
  257. void DoMenuCommand(long menuResult, WindowPtr window);
  258. void DoSave (WindowPtr window);
  259. void SendToHistory(TEHandle te);
  260. void GetPreferences(void);
  261. void SetDefaultPrefs(void);
  262. void GetWindowPos(WindowPtr window, Rect *r);
  263. void SetWindowPos(void);
  264. void SetPrefValues(ControlHandle *control);
  265. void SetPreferences(void);
  266. void UpdatePreferences(void);
  267. void CenterRect(Rect *r);
  268. void AdjustScrollBars(dataPeek doc);
  269. void SetScrollBar(ControlHandle control, short max, short value);
  270. void DoActivate(WindowPtr window, Boolean isActive);
  271. void DoUpdate(WindowPtr window);
  272. void TextUpdate(textHandle t);
  273. void InvertText(textHandle t, long start, long end);
  274. void FlushText(WindowPtr window);
  275. Boolean StoreChar(WindowPtr window, char c, Size max_size);
  276. void VScrollText(textHandle t, long dv);
  277. void HScrollText(textHandle t, short dh);
  278. void ScrollGraph(dataPeek doc, short dh, short dv);
  279. void DoGrowWindow(WindowPtr window, EventRecord *event);
  280. Boolean DoNew(short index, Rect *boundsRect);
  281. void OpenOutput(short windowType);
  282. void OpenInput(void);
  283. Boolean OpenGraph(void);
  284. void DoClose(WindowPtr window);
  285. pascal ProcPtr GetOldClikLoop(void);
  286. pascal void ClikLoop(void);
  287. void FixViewRect(WindowPtr window);
  288. void FixScrollBar(dataPeek doc);
  289. void Error(short error);
  290. void set_input (char *text, long len);
  291.  
  292. extern pascal void AsmClikLoop(void);
  293.  
  294. unsigned long DoRead(char *text, unsigned long len)
  295. {
  296.     bufHandle buffer;
  297.     long index, begin, maxLength;
  298.     static long curPos = 0;
  299.     
  300.     buffer = (*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  301.     while (true)
  302.         if (((index = (*buffer)[1]) < **buffer) || (curPos > 0)) {
  303.             begin = (*buffer)[index] + curPos;
  304.             if (len > (maxLength = (*buffer)[index + 1] - begin - nCR + 1))
  305.                 len = maxLength;
  306.             BlockMove((char *) (*(*((textHandle) ((dataPeek) CAMLHistory)->h))->hText + begin), text, len);
  307.             if ((curPos += len) == (*buffer)[index + 1] - (*buffer)[index] - nCR + 1) {
  308.                 curPos = 0;
  309.                 (*buffer)[1]++;
  310.             }
  311.             DoWrite(CAMLPrinter, text, len);
  312.             return len;
  313.         }else{
  314.             reading = 1;
  315.             LookEvent(15);
  316.             reading = 0;
  317.         }
  318. }
  319.  
  320. void DoWrite(WindowPtr window, char *text, long len)
  321. {
  322.   GrafPtr port;
  323.   long d, line, beg_str, end_str, invis, old_lines, first_line, old_length;
  324.   char c;
  325.   textHandle h;
  326.   RgnHandle clipRgn;
  327.   Rect r;
  328.   Size max_size = (window == CAMLHistory) ? Pref->HiMaxSize : Pref->PrMaxSize;
  329.   Size s;
  330.   int drawn = 0;
  331.  
  332.   h = (textHandle) ((dataPeek) window)->h;
  333. #define t (*h)
  334.   s = GetHandleSize (t->hText);
  335.   GetPort(&port);
  336.   SetPort(window);
  337.   clipRgn = NewRgn();
  338.   GetClip(clipRgn);
  339.   r = t->viewRect;
  340.   ClipRect(&r);
  341.  
  342.   first_line = t->firstLine;
  343.   old_length = t->teLength;
  344.   old_lines = t->nLines;
  345.   line = t->last_line_length;
  346.   end_str = 0;
  347.   beg_str = 0;
  348.   while (end_str < len){
  349.     if (line >= MAXCHAR){
  350.       c = '\n';
  351.       invis = 0;
  352.     }else{
  353.       c = text [end_str];
  354.       ++end_str;
  355.       invis = 1;
  356.     }
  357.     if (s != 0){
  358.       if (t->teLength >= s){
  359.         if (s < max_size){
  360.           SetHandleSize (t->hText, s + TEBLOCK);
  361.           s = GetHandleSize (t->hText);
  362.         }
  363.         if (t->teLength >= s){
  364.           FlushText (window);
  365.           drawn = 1;
  366.         }
  367.       }
  368.       /* if (t->teLength >= s) bug (); */
  369.       (*t->hText) [t->teLength++] = c;
  370.     }else{
  371.       end_str -= invis;
  372.       break;
  373.     }
  374.     if (c == '\n'){
  375.       if (line * CHARWIDTH > t->destRect.right - t->destRect.left)
  376.         t->destRect.right = t->destRect.left + line * CHARWIDTH;
  377.       line = 0;
  378.       ++t->nLines;
  379.       beg_str = end_str;
  380.     }else{
  381.       ++line;
  382.     }
  383.   }
  384.   if (line * CHARWIDTH > t->destRect.right - t->destRect.left)
  385.     t->destRect.right = t->destRect.left + line * CHARWIDTH;
  386.   if (!drawn){
  387.     t->firstLine = old_length - t->last_line_length;        /* old last line length */
  388.     t->viewRect.top = t->destRect.top + t->lineHeight * (old_lines - 1);
  389.     TextUpdate (h);
  390.     t->firstLine = first_line;
  391.     t->viewRect.top = r.top;
  392.   }
  393.  
  394.   t->last_line_length = line;
  395.  
  396.   d = t->nLines - (t->viewRect.bottom - t->destRect.top) / t->lineHeight;
  397.   if (d > 0
  398.       && ((t->viewRect.bottom - t->destRect.top) / t->lineHeight >= old_lines
  399.           || Pref->AutoScroll)){
  400.     VScrollText(h, -d);
  401.   }
  402.   
  403.   SetClip(clipRgn);
  404.   DisposeRgn(clipRgn);
  405.   AdjustScrollBars((dataPeek) window);
  406.   SetPort(port);
  407. #undef t
  408. }
  409.  
  410. void Initialize(void)
  411. {
  412.     Handle menuBar;
  413.     SysEnvRec Mac;
  414.     
  415.     if (GetApplLimit () > *(char **) CurStackBase - 40000){
  416.       SetApplLimit (*(char **) CurStackBase - 40000);
  417.     }
  418.     MaxApplZone();
  419.     InitGraf((Ptr) &qd.thePort);
  420.     InitFonts();
  421.     InitWindows();
  422.     InitMenus();
  423.     TEInit();
  424.     InitDialogs(nil);
  425.     InitCursor();
  426.     
  427.     menuBar = GetNewMBar(rMenuBar);
  428.     if (menuBar == nil) {
  429.         Error(eNoMemory);
  430.         ExitToShell();
  431.     }
  432.     SetMenuBar(menuBar);
  433.     DisposHandle(menuBar);
  434.     AddResMenu(GetMHandle(mApple), 'DRVR');
  435.     DrawMenuBar();
  436.     if ((SysEnvirons(Version, &Mac) != noErr) || (Mac.machineType < 0)) {
  437.         Error(eWrongMachine);
  438.         ExitToShell();
  439.     }
  440.     color_qd = Mac.hasColorQD;
  441.     WNEAvailable = (NGetTrapAddress(_WaitNextEvent, ToolTrap) != GetTrapAddress(_Unimplemented));
  442.     inForeground = true;
  443.     WList = nil;
  444.     GetPreferences ();
  445.     SetWindowPos ();
  446.     OpenInput();
  447.     OpenOutput(tOutput);
  448.     OpenOutput(tHistory);
  449.     indexBuffer = 2;
  450. }
  451.  
  452. void Quit(void)
  453. {
  454.   if (Pref->SavePos) {
  455.     if (CAMLInput != nil)
  456.       GetWindowPos(CAMLInput, &Pref->LiWindowRect);
  457.     if (CAMLPrinter != nil)
  458.       GetWindowPos(CAMLPrinter, &Pref->PrWindowRect);
  459.     if (CAMLHistory != nil)
  460.       GetWindowPos(CAMLHistory, &Pref->HiWindowRect);
  461.     if (CAMLGraph != nil)
  462.       GetWindowPos (CAMLGraph, &Pref->GrWindowRect);
  463.     UpdatePreferences();
  464.   }
  465.   while (WList != nil)
  466.     DoClose((WindowPtr) WList);
  467.   ExitToShell();
  468. }
  469.  
  470. #define Incr(x) (x) = ((x) + 1) % N_graph_events
  471.  
  472. void push_graph_event (void)
  473. {
  474.   Incr (graph_event_head);
  475.   if (graph_event_head == graph_event_tail) Incr (graph_event_tail);
  476. }
  477.  
  478. void LookGraphEvent (EventRecord *result, int move_ok, int poll)
  479. {
  480.   Point mouse_before, mouse_after;
  481.   int i;
  482.  
  483.   if (poll){
  484.     GetMouse (&result->where);
  485.     LocalToGlobal (&result->where);
  486.     result->modifiers = Button () ? 0 : btnState;
  487.     result->what = nullEvent;
  488.     for (i = graph_event_tail; i != graph_event_head; Incr (i)){
  489.       if (graph_event_queue [i].what == keyDown){
  490.         result->what = keyDown;
  491.         result->message = graph_event_queue [i].message;
  492.         break;
  493.       }
  494.     }
  495.     return;
  496.   }
  497.   if (graph_event_head != graph_event_tail){
  498.     *result = graph_event_queue [graph_event_tail];
  499.     Incr (graph_event_tail);
  500.     return;
  501.   }
  502.   GetMouse (&mouse_before);
  503.   LocalToGlobal (&mouse_before);
  504.   while (1){
  505.     wait_graph_move = move_ok;
  506.     LookEvent (15);
  507.     GetMouse (&mouse_after);
  508.     LocalToGlobal (&mouse_after);
  509.     if (move_ok && mouse_after != mouse_before
  510.         || graph_event_head != graph_event_tail)
  511.       break;
  512.   }
  513.   if (graph_event_head == graph_event_tail){
  514.     *result = graph_event_queue [graph_event_head];
  515.     result->what = nullEvent;
  516.   }else{
  517.     *result = graph_event_queue [graph_event_tail];
  518.     Incr (graph_event_tail);
  519.   }
  520. }
  521.  
  522. #undef Incr
  523.  
  524. void LookEvent(unsigned long delay)
  525. {
  526.     EventRecord event;
  527.     Boolean eventToProcess;
  528.     RgnHandle mouseRgn;
  529.     WindowPtr window;
  530.     
  531.     do {
  532.         mouseRgn = (inForeground) ? FixCursor() : nil;
  533.         if (inForeground && isTEWindow(window = FrontWindow()))
  534.             TEIdle((TEHandle) ((dataPeek) window)->h);
  535.         if (WNEAvailable)
  536.             eventToProcess = WaitNextEvent(everyEvent, &event, delay, mouseRgn);
  537.         else {
  538.             SystemTask();
  539.             eventToProcess = GetNextEvent(everyEvent, &event);
  540.         }
  541.         graph_event_queue [graph_event_head] = event;
  542.         if (mouseRgn != nil)
  543.             DisposeRgn(mouseRgn);
  544.         if (eventToProcess)
  545.             DoEvent(&event);
  546.     } while (eventToProcess);
  547. }
  548.  
  549. RgnHandle FixCursor(void)
  550. {
  551.     WindowPtr window;
  552.     Point mouse;
  553.     long h;
  554.     Rect r;
  555.     RgnHandle mouseRgn;
  556.     RgnHandle screenRgn;
  557.     
  558.     window = FrontWindow();
  559.     if (isTEWindow(window) || isTextWindow(window)) {
  560.         SetPort(window);
  561.         GetMouse(&mouse);
  562.         h = ((dataPeek) window)->h;
  563.         r = isTEWindow(window) ? (*((TEHandle) h))->viewRect : (*((textHandle) h))->viewRect;
  564.         mouseRgn = NewRgn();
  565.         RectRgn(mouseRgn, &r);
  566.         OffsetRgn(mouseRgn, -window->portBits.bounds.left, -window->portBits.bounds.top);
  567.         if (PtInRect(mouse, &r))
  568.             SetCursor(*GetCursor(iBeamCursor));
  569.         else {
  570.             SetCursor(&qd.arrow);
  571.             r = qd.screenBits.bounds;
  572.             screenRgn = NewRgn();
  573.             RectRgn(screenRgn, &r);
  574.             DiffRgn(screenRgn, mouseRgn, mouseRgn);
  575.             DisposeRgn(screenRgn);
  576.         }
  577.         return mouseRgn;
  578.     }
  579.     SetCursor(&qd.arrow);
  580.     if (isGraphWindow (window) && wait_graph_move){
  581.       wait_graph_move = 0;
  582.       GetMouse (&mouse);
  583.       mouseRgn = NewRgn ();
  584.       SetRectRgn (mouseRgn, mouse.h, mouse.v, mouse.h + 1, mouse.v + 1);
  585.       OffsetRgn (mouseRgn, -window->portBits.bounds.left, -window->portBits.bounds.top);
  586.       return mouseRgn;
  587.     }
  588.     return nil;
  589. }
  590.  
  591. void DoEvent(EventRecord *event)
  592. {
  593.     char key;
  594.     WindowPtr window;
  595.     TEHandle te;
  596.     Point thePoint;
  597.     
  598.     switch (event->what) {
  599.         case mouseDown:
  600.             DoMouseDown(event);
  601.             break;
  602.         case mouseUp:
  603.             push_graph_event ();
  604.             break;
  605.         case keyDown:
  606.         case autoKey:
  607.             key = event->message & charCodeMask;
  608.             window = FrontWindow();
  609.             if (event->modifiers & cmdKey)
  610.                 if (key == CReturn)
  611.                     key = Enter;
  612.                 else {
  613.                     AdjustMenus(window);
  614.                     DoMenuCommand(MenuKey(key), window);
  615.                     return;
  616.                 }
  617.             switch (WindowType(window)) {
  618.                 case tInput:
  619.                     te = (TEHandle) ((dataPeek) window)->h;
  620.                     if (Pref->Return && ((key == CReturn) || (key == Enter)))
  621.                         key = CReturn + Enter - key;
  622.                     if (key != Enter) {
  623.                         if (((*te)->teLength + (*te)->selEnd - (*te)->selStart + 1 < MAXSHORT)
  624.                             || (key == DelKey)
  625.                             || (key < ' '))
  626.                             TEKey(key, te);
  627.                         else
  628.                             Error(eTooMuchChars);
  629.                     } else {
  630.                         SendToHistory(te);
  631.                         if (event->modifiers & optionKey) {
  632.                             AdjustMenus(window);
  633.                             DoMenuCommand(MenuKey('N'), window);
  634.                         } else
  635.                             indexBuffer = **(*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  636.                     }
  637.                     AdjustScrollBars((dataPeek) window);
  638.                     break;
  639.                 case tOutput:
  640.                 case tHistory:
  641.                     SysBeep(1);
  642.                     break;
  643.                 case tGraphic:
  644.                     push_graph_event ();
  645.                     break;
  646.             }
  647.             break;
  648.         case activateEvt:
  649.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag));
  650.             break;
  651.         case updateEvt:
  652.             DoUpdate(window = (WindowPtr) event->message);
  653.             break;
  654.         case diskEvt:
  655.             if (HiWord(event->message) != noErr) {
  656.                 SetPt(&thePoint, DIX, DIY);
  657.                 DIBadMount(thePoint, event->message);
  658.             }
  659.             break;
  660.         case app4Evt:
  661.             if (((event->message & osEvtMessageMask) >> 24) == suspendResumeMessage) {
  662.                 inForeground = (event->message & resumeFlag);
  663.                 DoActivate(FrontWindow(), inForeground);
  664.             }
  665.             break;
  666.     }
  667. }
  668.  
  669. void DoMouseDown(EventRecord *event)
  670. {
  671.     WindowPtr window;
  672.     short part;
  673.     Rect r;
  674.     
  675.     part = FindWindow(event->where, &window);
  676.     switch (part) {
  677.         case inMenuBar:
  678.             AdjustMenus(window = FrontWindow());
  679.             DoMenuCommand(MenuSelect(event->where), window);
  680.             break;
  681.         case inSysWindow:
  682.             SystemClick(event, window);
  683.             break;
  684.         case inContent:
  685.             if (window != FrontWindow())
  686.                 SelectWindow(window);
  687.             else
  688.                 DoClickContent(window, event);
  689.             break;
  690.         case inDrag:
  691.             r = qd.screenBits.bounds;
  692.             r.top += GetMBarHeight();
  693.             InsetRect(&r, MARGINDRAG, MARGINDRAG);
  694.             DragWindow(window, event->where, &r);
  695.             break;
  696.         case inGrow:
  697.             DoGrowWindow(window, event);
  698.             break;
  699.         case inGoAway:
  700.             HideWindow(window);
  701.             break;
  702.         case inZoomIn:
  703.         case inZoomOut:
  704.             if (TrackBox(window, event->where, part)) {
  705.                 SetPort(window);
  706.                 EraseRect(&window->portRect);
  707.                 ZoomWindow(window, part, window == FrontWindow());
  708.                 FixViewRect(window);
  709.                 if (isGraphWindow(window)) {
  710.                     switch (part) {
  711.                         case inZoomIn:
  712.                             gp->destRect = gp->destRectZoom;
  713.                             break;
  714.                         case inZoomOut:
  715.                             gp->destRectZoom = gp->destRect;
  716.                             gp->destRect = gp->viewRect;
  717.                             gp->destRect.right = gp->destRect.left + SIZEX;
  718.                             gp->destRect.top = gp->destRect.bottom - SIZEY;
  719.                     }
  720.                     ClipRect(&CAMLGraph->portRect);
  721.                 }
  722.                 InvalRect(&window->portRect);
  723.                 (*((dataPeek) window)->vSBar)->contrlVis = inVisible;        /* pour que AdjustScrollBars ne redessine pas    */
  724.                 (*((dataPeek) window)->hSBar)->contrlVis = inVisible;        /* les controles, ce sera fait via le updateEvt    */
  725.                 AdjustScrollBars((dataPeek) window);
  726.                 FixScrollBar((dataPeek) window);
  727.             }
  728.             break;
  729.     }
  730. }
  731.  
  732. void DoClickContent(WindowPtr window, EventRecord *event)
  733. {
  734.     Point mouse;
  735.     dataPeek doc;
  736.     short max, scale;
  737.     long realMax;
  738.     ControlHandle control;
  739.     TEHandle te;
  740.     TEPtr pte;
  741.     textHandle t;
  742.     textPtr pt;
  743.     graphPeek g;
  744.     
  745.     mouse = event->where;
  746.     doc = (dataPeek) window;
  747.     SetPort(window);
  748.     GlobalToLocal(&mouse);
  749.     switch (WindowType(window)) {
  750.         case tInput:
  751.             te = (TEHandle) doc->h;
  752.             switch (FindControl(mouse, window, &control)) {
  753.                 case 0:
  754.                     if (PtInRect(mouse, &(*te)->viewRect)) {
  755.                         TEClick(mouse, ((event->modifiers & shiftKey) != 0), te);
  756.                         AdjustScrollBars(doc);
  757.                     }
  758.                     break;
  759.                 case inThumb:
  760.                     pte = *te;
  761.                     if (control == doc->vSBar) {
  762.                         max = pte->nLines - (pte->viewRect.bottom - pte->viewRect.top) / pte->lineHeight;    /* il faut avoir le max reel...    */
  763.                         max += (pte->teLength) && (*(*pte->hText + pte->teLength - 1) == '\n');
  764.                     } else
  765.                         max = TEWSIZE - (pte->viewRect.right - pte->viewRect.left + CHARWIDTH - 1) / CHARWIDTH;
  766.                     if (max < GetCtlValue(control)) {
  767.                         if (max < 1)
  768.                             max = 1;
  769.                         (*control)->contrlValue = max;
  770.                         (*control)->contrlMax = max;
  771.                     }
  772.                     if (TrackControl(control, mouse, nil)) {
  773.                         pte = *te;
  774.                         if (control == doc->vSBar)
  775.                             TEScroll(0, pte->viewRect.top - pte->destRect.top - GetCtlValue(control) * pte->lineHeight, te);
  776.                         else
  777.                             TEScroll(pte->viewRect.left - pte->destRect.left - GetCtlValue(control) * CHARWIDTH, 0, te);
  778.                     }
  779.                     AdjustScrollBars(doc);
  780.                     break;
  781.                 default:
  782.                     TrackControl(control, mouse, (ProcPtr) DoClickTESBar);
  783.                     break;
  784.             }
  785.             break;
  786.         case tOutput:
  787.         case tHistory:
  788.             t = (textHandle) doc->h;
  789.             switch (FindControl(mouse, window, &control)) {
  790.                 case 0:
  791.                     if (PtInRect(mouse, &(*t)->viewRect))
  792.                         SelectText(t, mouse, event->modifiers & shiftKey);
  793.                     break;
  794.                 case inThumb:
  795.                     pt = *t;
  796.                     if (control == doc->vSBar) {
  797.                         realMax = pt->nLines - (pt->viewRect.bottom - pt->viewRect.top) / pt->lineHeight;
  798.                         scale = 1 + realMax / MAXSHORT;
  799.                         max = realMax / scale;
  800.                     } else
  801.                         max = (pt->destRect.right - pt->destRect.left - pt->viewRect.right + pt->viewRect.left + pt->width - 1) / pt->width;
  802.                     if (max < GetCtlValue(control)) {
  803.                         if (max < 1)
  804.                             max = 1;
  805.                         (*control)->contrlValue = max;
  806.                         (*control)->contrlMax = max;
  807.                     }
  808.                     if (TrackControl(control, mouse, nil)) {
  809.                         pt = *t;
  810.                         if (control == doc->vSBar)
  811.                             VScrollText(t, (pt->viewRect.top - pt->destRect.top) / pt->lineHeight - GetCtlValue(control) * scale);
  812.                         else
  813.                             HScrollText(t, (pt->viewRect.left - pt->destRect.left) / pt->width - GetCtlValue(control));
  814.                     }
  815.                     AdjustScrollBars(doc);
  816.                     break;
  817.                 default:
  818.                     TrackControl(control, mouse, (ProcPtr) DoClickTextSBar);
  819.                     break;
  820.             }
  821.             break;
  822.         case tGraphic:
  823.             switch (FindControl(mouse, window, &control)) {
  824.                 case 0:
  825.                     push_graph_event ();
  826.                     break;
  827.                 case inThumb:
  828.                     if (TrackControl(control, mouse, nil)) {
  829.                         g = (graphPeek) doc->h;
  830.                         if (control == doc->vSBar)
  831.                             ScrollGraph(doc, 0, g->viewRect.top - g->destRect.top - GetCtlValue(control));
  832.                         else
  833.                             ScrollGraph(doc, g->viewRect.left - g->destRect.left - GetCtlValue(control), 0);
  834.                     }    
  835.                     break;
  836.                 default:
  837.                     TrackControl(control, mouse, (ProcPtr) DoClickGraphSBar);
  838.                     break;
  839.             }
  840.             break;
  841.     }
  842. }
  843.  
  844. void SelectText(textHandle t, Point mouse, short extend)
  845. {
  846.     long org, pos, oldpos;
  847.     char *text;
  848.     
  849.     oldpos = MouseToText(*t, mouse);
  850.     if (extend) {
  851.         pos = ((*t)->selStart + (*t)->selEnd) / 2;
  852.         if (oldpos < pos) {
  853.             org = (*t)->selEnd;
  854.             InvertText(t, oldpos, (*t)->selStart);
  855.             (*t)->selStart = oldpos;
  856.         } else {
  857.             org = (*t)->selStart;
  858.             InvertText(t, (*t)->selEnd, oldpos);
  859.             (*t)->selEnd = oldpos;
  860.         }
  861.     } else {
  862.         InvertText(t, (*t)->selStart, (*t)->selEnd);
  863.         (*t)->selStart = oldpos;
  864.         (*t)->selEnd = oldpos;
  865.         org = oldpos;
  866.     }
  867.     while (StillDown()) {
  868.         GetMouse(&mouse);
  869.         pos = MouseToText(*t, mouse);
  870.         if (pos < 0) {
  871.             switch (pos) {
  872.                 case Ttop:
  873.                     if ((*t)->viewRect.top > (*t)->destRect.top)
  874.                         VScrollText(t, 1);
  875.                     pos = (*t)->firstLine;
  876.                     break;
  877.                 case Tbottom:
  878.                     if (((*t)->viewRect.bottom - (*t)->destRect.top) / (*t)->lineHeight < (*t)->nLines)
  879.                         VScrollText(t, -1);
  880.                     SetPt(&mouse, (*t)->viewRect.right - 1, (*t)->viewRect.bottom - 1);
  881.                     for (pos = MouseToText(*t, mouse), text = *(*t)->hText; (pos < (*t)->teLength) && (*(text + pos) != '\n'); pos++)
  882.                         ;
  883.                     if (*(text + pos) == '\n')
  884.                         pos++;
  885.                     break;
  886.                 case Tleft:
  887.                     if ((*t)->viewRect.left > (*t)->destRect.left)
  888.                         HScrollText(t, 1);
  889.                     mouse.h = (*t)->viewRect.left;
  890.                     pos = MouseToText(*t, mouse);
  891.                     break;
  892.                 case Tright:
  893.                     if ((*t)->viewRect.right < (*t)->destRect.right)
  894.                         HScrollText(t, -1);
  895.                     mouse.h = (*t)->viewRect.right - 1;
  896.                     pos = MouseToText(*t, mouse);
  897.                     break;
  898.             }
  899.             AdjustScrollBars((dataPeek) FrontWindow());
  900.         }
  901.         if (pos != oldpos) {
  902.             InvertText(t, pos, oldpos);
  903.             (*t)->selStart = (pos >= org) ? org : pos;
  904.             (*t)->selEnd = (pos >= org) ? pos : org;
  905.             oldpos = pos;
  906.         }
  907.     }
  908. }
  909.  
  910. long MouseToText(textPtr t, Point mouse)
  911. {
  912.     long i;
  913.     short nlines, n;
  914.     char *text;
  915.     
  916.     if (mouse.v < t->viewRect.top)
  917.         return Ttop;
  918.     if (mouse.v >= t->viewRect.bottom)
  919.         return Tbottom;
  920.     if (mouse.h < t->viewRect.left - t->width / 2)
  921.         return Tleft;
  922.     if (mouse.h >= t->viewRect.right)
  923.         return Tright;
  924.     nlines = (t->viewRect.bottom - t->viewRect.top) / t->lineHeight;
  925.     i = t->firstLine;
  926.     text = *t->hText;
  927.     for (n = 1; (i < t->teLength) && (n <= nlines) && (mouse.v >= t->viewRect.top + n * t->lineHeight); i++, n++)
  928.         while ((i < t->teLength) && (*(text + i) != '\n'))
  929.             i++;
  930.     if ((i < t->teLength) && (mouse.v < t->viewRect.top + n * t->lineHeight)) {
  931.         for (n = (t->viewRect.left - t->destRect.left) / t->width; (i < t->teLength) && (n > 0) && (*(text + i) != '\n'); i++, n--)
  932.             ;
  933.         if (n == 0)
  934.             while ((i < t->teLength) && (mouse.h >= t->viewRect.left + n * t->width + t->width / 2) && (*(text + i) != '\n'))
  935.                 i++, n++;
  936.         return i;
  937.     }
  938.     return t->teLength;
  939. }
  940.  
  941. pascal void DoClickTESBar(ControlHandle control, short part)
  942. {
  943.     dataPeek doc;
  944.     TEPtr te;
  945.     short value, d;
  946.     
  947.     if (part) {
  948.         doc = (dataPeek) (*control)->contrlOwner;
  949.         value = GetCtlValue(control);
  950.         te = *((TEHandle) doc->h);
  951.         switch (part) {
  952.             case inUpButton:
  953.             case inDownButton:
  954.                 d = (control == doc->vSBar) ? 1 : NSCHAR;
  955.                 break;
  956.             case inPageUp:
  957.             case inPageDown:
  958.                 if (control == doc->vSBar)
  959.                     d = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight - VSCROLLVIS;
  960.                 else
  961.                     d = (te->viewRect.right - te->viewRect.left) / CHARWIDTH - HSCROLLVIS;
  962.                 break;
  963.         }
  964.         if ((part == inDownButton) || (part == inPageDown))
  965.             d = -d;
  966.         if (d > value)
  967.             d = value;
  968.         else
  969.             if (value - d > GetCtlMax(control))
  970.                 d = value - GetCtlMax(control);
  971.         if (control == doc->vSBar)
  972.             TEScroll(0, d * te->lineHeight, (TEHandle) doc->h);
  973.         else {
  974.             d *= CHARWIDTH;
  975.             if (part == inUpButton)
  976.                 d += (te->viewRect.left - te->destRect.left) % CHARWIDTH;
  977.             TEScroll(d, 0, (TEHandle) doc->h);
  978.         }
  979.         AdjustScrollBars(doc);                    /* les scroll bars peuvent devenir inactives, ce    */
  980.     }                                            /* que ne permet pas un simple SetCtlValue.            */
  981. }
  982.  
  983. pascal void DoClickTextSBar(ControlHandle control, short part)
  984. {
  985.     dataPeek doc;
  986.     textPtr t;
  987.     short d;
  988.     long max, value;
  989.     
  990.     if (part) {
  991.         doc = (dataPeek) (*control)->contrlOwner;
  992.         t = *((textHandle) doc->h);
  993.         if (control == doc->vSBar) {
  994.             max = t->nLines - (t->viewRect.bottom - t->viewRect.top) / t->lineHeight;        /* il faut les vraies valeurs, sans passer    */
  995.             value = (t->viewRect.top - t->destRect.top) / t->lineHeight;                    /* par le facteur d'echelle...                */
  996.             if (max < value)
  997.                 max = value;
  998.         } else {
  999.             max = GetCtlMax(control);
  1000.             value = GetCtlValue(control);
  1001.         }
  1002.         switch (part) {
  1003.             case inUpButton:
  1004.             case inDownButton:
  1005.                 d = (control == doc->vSBar) ? 1 : NSCHAR;
  1006.                 break;
  1007.             case inPageUp:
  1008.             case inPageDown:
  1009.                 if (control == doc->vSBar)
  1010.                     d = (t->viewRect.bottom - t->viewRect.top) / t->lineHeight - VSCROLLVIS;
  1011.                 else
  1012.                     d = (t->viewRect.right - t->viewRect.left) / t->width - HSCROLLVIS;
  1013.                 break;
  1014.         }
  1015.         if ((part == inDownButton) || (part == inPageDown))
  1016.             d = -d;
  1017.         if (d > value)
  1018.             d = value;
  1019.         else
  1020.             if (value - d > max)
  1021.                 d = - ((short) (max - value));
  1022.         if (control == doc->vSBar)
  1023.             VScrollText((textHandle) doc->h, d);
  1024.         else
  1025.             HScrollText((textHandle) doc->h, d);
  1026.         AdjustScrollBars(doc);
  1027.     }
  1028. }
  1029.  
  1030. pascal void DoClickGraphSBar(ControlHandle control, short part)
  1031. {
  1032.     dataPeek doc;
  1033.     graphPeek g;
  1034.     short d, value;
  1035.     
  1036.     if (part) {
  1037.         doc = (dataPeek) (*control)->contrlOwner;
  1038.         g = (graphPeek) doc->h;
  1039.         value = GetCtlValue(control);
  1040.         switch (part) {
  1041.             case inUpButton:
  1042.             case inDownButton:
  1043.                 d = NSPIXEL;
  1044.                 break;
  1045.             case inPageUp:
  1046.             case inPageDown:
  1047.                 if (control == doc->vSBar)
  1048.                     d = g->viewRect.bottom - g->viewRect.top;
  1049.                 else
  1050.                     d = g->viewRect.right - g->viewRect.left;
  1051.                 d -= NSPIXEL;
  1052.                 break;
  1053.         }
  1054.         if ((part == inDownButton) || (part == inPageDown))
  1055.             d = -d;
  1056.         if (d > value)
  1057.             d = value;
  1058.         else
  1059.             if (value - d > GetCtlMax(control))
  1060.                 d = value - GetCtlMax(control);
  1061.         if (control == doc->vSBar)
  1062.             ScrollGraph(doc, 0, d);
  1063.         else
  1064.             ScrollGraph(doc, d, 0);
  1065.     }
  1066. }
  1067.  
  1068. void AdjustMenus(WindowPtr window)
  1069. {
  1070.     MenuHandle hFile, hEdit, hCaml;
  1071.     TEPtr te;
  1072.     textPtr t;
  1073.     Boolean selAll, selection, paste, CutClear, prevEnt, nextEnt, save;
  1074.     
  1075.     if (isTEWindow(window)) {
  1076.         te = *((TEHandle) ((dataPeek) window)->h);
  1077.         selAll = (te->teLength > 0);
  1078.         selection = (te->selStart < te->selEnd);
  1079.         paste = (TEGetScrapLen() > 0);
  1080.         CutClear = selection;
  1081.         prevEnt = (indexBuffer > 2);
  1082.         nextEnt = (indexBuffer < **(*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer);
  1083.         save = false;
  1084.     } else {
  1085.         if (isTextWindow(window)) {
  1086.             t = *((textHandle) ((dataPeek) window)->h);
  1087.             selAll = (t->teLength > 0);
  1088.             selection = (t->selStart < t->selEnd);
  1089.             save = true;
  1090.         } else {
  1091.             selAll = false;
  1092.             selection = false;
  1093.             save = false;
  1094.         }
  1095.         paste = false;
  1096.         CutClear = false;
  1097.         prevEnt = false;
  1098.         nextEnt = false;
  1099.     }
  1100.     hFile = GetMHandle (mFile);
  1101.     hEdit = GetMHandle(mEdit);
  1102.     hCaml = GetMHandle(mCaml);
  1103.     if (selAll)
  1104.         EnableItem(hEdit, iSelAll);
  1105.     else
  1106.         DisableItem(hEdit, iSelAll);
  1107.     if (selection)
  1108.         EnableItem(hEdit, iCopy);
  1109.     else
  1110.         DisableItem(hEdit, iCopy);
  1111.     if (paste)
  1112.         EnableItem(hEdit, iPaste);
  1113.     else
  1114.         DisableItem(hEdit, iPaste);
  1115.     if (CutClear) {
  1116.         EnableItem(hEdit, iCut);
  1117.         EnableItem(hEdit, iClear);
  1118.     } else {
  1119.         DisableItem(hEdit, iCut);
  1120.         DisableItem(hEdit, iClear);
  1121.     }
  1122.     if (prevEnt)
  1123.         EnableItem(hCaml, iPrevEnt);
  1124.     else
  1125.         DisableItem(hCaml, iPrevEnt);
  1126.     if (nextEnt)
  1127.         EnableItem(hCaml, iNextEnt);
  1128.     else
  1129.         DisableItem(hCaml, iNextEnt);
  1130.     if (isGraphWindow(window) || (window == CAMLHistory))
  1131.         EnableItem(hFile, iClose);
  1132.     else
  1133.         DisableItem(hFile, iClose);
  1134.     if (save){
  1135.         EnableItem (hFile, iSave);
  1136.     }else{
  1137.         DisableItem (hFile, iSave);
  1138.     }
  1139.     if (reading){
  1140.       EnableItem (hFile, iInclude);
  1141.       EnableItem (hFile, iCompile);
  1142.       EnableItem (hFile, iLoad);
  1143.       EnableItem (hFile, iLoadObject);
  1144.       EnableItem (hCaml, iGC);
  1145.     }else{
  1146.       DisableItem (hFile, iInclude);
  1147.       DisableItem (hFile, iCompile);
  1148.       DisableItem (hFile, iLoad);
  1149.       DisableItem (hFile, iLoadObject);
  1150.       DisableItem (hCaml, iGC);
  1151.     }
  1152. }
  1153.  
  1154. void set_input (char *text, long len)
  1155. {
  1156.   Rect r;
  1157.   TEHandle te = (TEHandle) ((dataPeek) CAMLInput)->h;
  1158.  
  1159.   SetPort (CAMLInput);
  1160.   TEDeactivate(te);
  1161.   TESetSelect(0, (*te)->teLength, te);
  1162.   TEDelete(te);
  1163.   TEActivate(te);
  1164.   if (len > 0) {
  1165.       TESetText (text, len, te);
  1166.       r = CAMLInput->portRect;
  1167.       r.right -= SBWIDTH - 1;
  1168.       r.bottom -= SBWIDTH - 1;
  1169.       EraseRect(&r);
  1170.       TEUpdate(&r, te);
  1171.   }
  1172.   AdjustScrollBars((dataPeek) CAMLInput);
  1173. }
  1174.  
  1175. void DoMenuCommand(long menuResult, WindowPtr window)
  1176. {
  1177.     short menuID, item, d;
  1178.     Str255 DAName;
  1179.     Handle h;
  1180.     textHandle t;
  1181.     TEHandle te;
  1182.     bufHandle buffer;
  1183.     
  1184.     if (menuID = HiWord(menuResult)) {
  1185.         item = LoWord(menuResult);
  1186.         switch (menuID) {
  1187.             case mApple:
  1188.                 switch (item) {
  1189.                     case iAbout:
  1190.                         h = GetResource('ALRT', rAboutAlert);
  1191.                         CenterRect((Rect *) *h);
  1192.                         Alert(rAboutAlert, nil);
  1193.                         break;
  1194.                     default:
  1195.                         GetItem(GetMHandle(mApple), item, DAName);
  1196.                         OpenDeskAcc(DAName);
  1197.                 }
  1198.                 break;
  1199.             case mFile:
  1200.                 switch (item) {
  1201.                     case iOpen:
  1202.                         break;
  1203.                     case iClose:
  1204.                         if (((WindowPeek) window)->windowKind < 0)
  1205.                             CloseDeskAcc(-((WindowPeek) window)->windowKind);
  1206.                         else
  1207.                             HideWindow(window);
  1208.                         break;
  1209.                     case iSave:
  1210.                         if (((WindowPeek) window)->windowKind < 0){
  1211.                           /* Desk Accessory.  Do nothing. */
  1212.                         }else{
  1213.                           DoSave (window);
  1214.                         }
  1215.                         break;
  1216.                     case iQuit:
  1217.                         Quit();
  1218.                         break;
  1219.                     case iInclude:
  1220.                         do_include ();
  1221.                         break;
  1222.                     case iCompile:
  1223.                         do_compile ();
  1224.                         break;
  1225.                     case iLoad:
  1226.                         do_load ();
  1227.                         break;
  1228.                     case iLoadObject:
  1229.                         do_load_object ();
  1230.                         break;
  1231.                 }
  1232.                 break;
  1233.             case mEdit:
  1234.                 if (!SystemEdit(item - 1))
  1235.                     switch (item) {
  1236.                         case iUndo:
  1237.                             break;
  1238.                         case iCut:
  1239.                             TECut((TEHandle) ((dataPeek) window)->h);
  1240.                             AdjustScrollBars((dataPeek) window);
  1241.                             break;
  1242.                         case iCopy:
  1243.                             if (isTEWindow(window))
  1244.                                 TECopy((TEHandle) ((dataPeek) window)->h);
  1245.                             else {
  1246.                                 t = (textHandle) ((dataPeek) window)->h;
  1247.                                 if ((*t)->selStart < (*t)->selEnd)
  1248.                                     if (ZeroScrap() != noErr)
  1249.                                         Error(eNoScrap);
  1250.                                     else {
  1251.                                         HLock((*t)->hText);
  1252.                                         if (PutScrap((*t)->selEnd - (*t)->selStart, 'TEXT', *(*t)->hText + (*t)->selStart) != noErr)
  1253.                                             Error(eNoScrapPut);
  1254.                                         HUnlock((*t)->hText);
  1255.                                     }
  1256.                             }
  1257.                             break;
  1258.                         case iPaste:
  1259.                             te = (TEHandle) ((dataPeek) window)->h;
  1260.                             if (TEGetScrapLen() + (*te)->teLength + (*te)->selStart - (*te)->selEnd < MAXSHORT) {
  1261.                                 TEPaste(te);
  1262.                                 AdjustScrollBars((dataPeek) window);
  1263.                             } else
  1264.                                 Error(eTooMuchChars);
  1265.                             break;
  1266.                         case iClear:
  1267.                             TEDelete((TEHandle) ((dataPeek) window)->h);
  1268.                             AdjustScrollBars((dataPeek) window);
  1269.                             break;
  1270.                         case iSelAll:
  1271.                             if (isTEWindow(window)) {
  1272.                                 te = (TEHandle) ((dataPeek) window)->h;
  1273.                                 TESetSelect(0, (*te)->teLength, te);
  1274.                             } else {
  1275.                                 t = (textHandle) ((dataPeek) window)->h;
  1276.                                 InvertText(t, 0, (*t)->selStart);
  1277.                                 InvertText(t, (*t)->selEnd, (*t)->teLength);
  1278.                                 (*t)->selStart = 0;
  1279.                                 (*t)->selEnd = (*t)->teLength;
  1280.                             }
  1281.                             break;
  1282.                     }
  1283.                 break;
  1284.             case mCaml:
  1285.                 switch (item) {
  1286.                     case iInterrupt:
  1287.                         HiliteMenu(0);
  1288.                         raise(SIGINT);
  1289.                         break;
  1290.                     case iShowHist:
  1291.                         ShowWindow(CAMLHistory);
  1292.                         SelectWindow(CAMLHistory);
  1293.                         break;
  1294.                     case iPrevEnt:
  1295.                     case iNextEnt:
  1296.                         t = (textHandle) ((dataPeek) CAMLHistory)->h;
  1297.                         buffer = (*t)->buffer;
  1298.                         d = 0;
  1299.                         if ((item == iPrevEnt) && (indexBuffer > 2))
  1300.                             d = -1;
  1301.                         if ((item == iNextEnt) && (indexBuffer < **buffer))
  1302.                             d = 1;
  1303.                         if (d != 0) {
  1304.                             indexBuffer += d;
  1305.                             HLock ((*t)->hText);
  1306.                             if (indexBuffer < **buffer){
  1307.                               set_input (*(*t)->hText + (*buffer) [indexBuffer],
  1308.                                          (*buffer) [indexBuffer + 1] - (*buffer)[indexBuffer] - nCR);
  1309.                             }else{
  1310.                               set_input (nil, 0);
  1311.                             }
  1312.                         }
  1313.                         break;
  1314.                     case iShowGraph:
  1315.                         ShowWindow(CAMLGraph);
  1316.                         SelectWindow(CAMLGraph);
  1317.                         break;
  1318.                     case iPref:
  1319.                         SetPreferences();
  1320.                         break;
  1321.                     case iGC:
  1322.                         do_gc ();
  1323.                         break;
  1324.                 }
  1325.                 break;
  1326.         }
  1327.         HiliteMenu(0);
  1328.     }
  1329. }
  1330.  
  1331. void DoSave (WindowPtr window)
  1332. {
  1333.   Handle text_handle = (*(textHandle) (((dataPeek) window)->h))->hText;
  1334.   DialogTHndl the_dialog;
  1335.   Point there;
  1336.   Str255 prompt, default_name;
  1337.   SFReply reply;
  1338.   short file_ref_num;
  1339.   short result_code;
  1340.   Rect sb = qd.screenBits.bounds;
  1341.   long count, creator;
  1342.   
  1343.   switch (WindowType (window)){
  1344.   case tOutput:
  1345.     GetIndString (prompt, rMiscStr, sSaveOutput);
  1346.     GetIndString (default_name, rMiscStr, sUntitled);
  1347.     break;
  1348.   case tHistory:
  1349.     GetIndString (prompt, rMiscStr, sSaveHistory);
  1350.     GetIndString (default_name, rMiscStr, sHistory_ml);
  1351.     break;
  1352.   default:
  1353.     return;
  1354.   }
  1355.   the_dialog = (DialogTHndl) GetResource ('DLOG', putDlgID);
  1356.   if (the_dialog != nil && *the_dialog != nil){
  1357.     Rect *r = &(*the_dialog)->boundsRect;
  1358.     
  1359.     CenterRect (r);
  1360.     there.h = r->left;
  1361.     there.v = r->top;
  1362.   }else{
  1363.     there.h = 200;
  1364.     there.v = 100;
  1365.   }
  1366.   SFPutFile (there, prompt, default_name, NULL, &reply);
  1367.   if (!reply.good) return;
  1368.   result_code = FSDelete (reply.fName, reply.vRefNum);
  1369.   if (result_code != noErr && result_code != fnfErr){
  1370.     Error (eCannotReplace);
  1371.     return;
  1372.   }
  1373.   memcpy (&creator, Pref->text_creator, 4);
  1374.   result_code = Create (reply.fName, reply.vRefNum, creator, 'TEXT');
  1375.   if (result_code != noErr){
  1376.     Error (eCannotCreate);
  1377.     return;
  1378.   }
  1379.   if (FSOpen (reply.fName, reply.vRefNum, &file_ref_num) != noErr){
  1380.     if (result_code == noErr) FSDelete (reply.fName, reply.vRefNum);
  1381.     Error (eCannotWrite);
  1382.     return;
  1383.   }
  1384.   count = (*(textHandle) (((dataPeek) window)->h))->teLength;
  1385.   if (FSWrite (file_ref_num, &count, *text_handle) != noErr){
  1386.     FSClose (file_ref_num);
  1387.     if (result_code == noErr) FSDelete (reply.fName, reply.vRefNum);
  1388.     Error (eCannotWrite);
  1389.     return;
  1390.   }
  1391.   FSClose (file_ref_num);
  1392.   return;
  1393. }
  1394.  
  1395. void SendToHistory(TEHandle te)
  1396. {
  1397.     bufHandle buffer;
  1398.     Size s;
  1399.     
  1400.     if ((*te)->teLength > 0) {
  1401.         buffer = (*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  1402.         if (((**buffer + 2) * sizeof(long)) > (s = GetHandleSize((Handle) buffer))) {
  1403.             SetHandleSize((Handle) buffer, s + BUFBLOCK);
  1404.             if (MemError() != noErr) {
  1405.                 Error(eNoMoreHistory);
  1406.                 return;
  1407.             }
  1408.         }
  1409.         HLock((*te)->hText);
  1410.         DoWrite(CAMLHistory, (char *) *(*te)->hText, (*te)->teLength);
  1411.         HUnlock((*te)->hText);
  1412.         DoWrite(CAMLHistory, "\n\n", nCR);                        /* le nombre de '\n' est egal a nCR    */
  1413.         (*buffer)[++**buffer] = (*((textHandle) ((dataPeek) CAMLHistory)->h))->teLength;
  1414.         TEDeactivate(te);
  1415.         TESetSelect(0, (*te)->teLength, te);
  1416.         TEDelete(te);
  1417.         TEActivate(te);
  1418.     }
  1419. }
  1420.  
  1421. void GetPreferences(void)
  1422. {
  1423.   PrefHandle resource;
  1424.   
  1425.   resource = (PrefHandle) GetResource ('PREF', rPREF);
  1426.   if (resource == nil){
  1427.     resource = (PrefHandle) NewHandle (sizeof (struct Preferences));
  1428.     AddResource ((Handle) resource, 'PREF', rPREF, "\p");
  1429.     (*resource)->magic_number = 'WRNG';
  1430.   }
  1431.   if (resource == nil){
  1432.     Error (eNoMemory);
  1433.     ExitToShell ();
  1434.   }
  1435.   if (GetHandleSize ((Handle) resource) != sizeof (struct Preferences))
  1436.     SetHandleSize ((Handle) resource, sizeof (struct Preferences));
  1437.   HLock ((Handle) resource);
  1438.   Pref = *resource;
  1439.   if (Pref->magic_number != 'CAML') SetDefaultPrefs ();
  1440. }
  1441.  
  1442. void SetDefaultPrefs (void)
  1443. {
  1444.   Pref->magic_number = 'CAML';
  1445.   Pref->Return = true;
  1446.   Pref->ShowHist = false;
  1447.   Pref->AutoScroll = true;
  1448.   Pref->SavePos = false;
  1449.   Pref->PrMaxSize = MAXSIZE * 1024;
  1450.   Pref->PrFlushSize = FLUSHSIZE * 1024;
  1451.   Pref->HiMaxSize = MAXSIZE / 2 * 1024;
  1452.   Pref->HiFlushSize = FLUSHSIZE / 2 * 1024;
  1453.   memcpy (Pref->text_creator, "ttxt", 4);
  1454. }
  1455.  
  1456. void GetWindowPos(WindowPtr window, Rect *r)
  1457. {
  1458.   Point *p = (Point *) r;
  1459.   
  1460.   SetPort (window);
  1461.   *r = window->portRect;
  1462.   LocalToGlobal (&p[0]);
  1463.   LocalToGlobal (&p[1]);
  1464. }
  1465.  
  1466. void fit_in_screen (Rect *w, Rect *screen)
  1467. {
  1468.   Rect temp;
  1469.  
  1470.   if (w->bottom - w->top > screen->bottom - screen->top){
  1471.     w->bottom = w->top + screen->bottom - screen->top;
  1472.   }
  1473.   if (!SectRect (w, screen, &temp)){
  1474.     w->bottom = screen->top + w->bottom - w->top;
  1475.     w->top = screen->top;
  1476.     w->right = screen->left + w->right - w->left;
  1477.     w->left = screen->left;
  1478.   }
  1479.   if (w->top < screen->top){
  1480.     w->bottom += screen->top - w->top;
  1481.     w->top = screen->top;
  1482.   }
  1483. }
  1484.  
  1485. void send_to_caml (char *text)
  1486. {
  1487.   set_input (text, strlen (text));
  1488.   SendToHistory ((TEHandle) ((dataPeek) CAMLInput)->h);
  1489.   indexBuffer = **(*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  1490. }
  1491.  
  1492. void SetWindowPos(void)
  1493. {
  1494.   Rect screen;
  1495.  
  1496.   screen = qd.screenBits.bounds;
  1497.   screen.top += GetMBarHeight() + SBWIDTH;
  1498.   InsetRect(&screen, MARGINDRAG, MARGINDRAG);
  1499.   if (Pref->SavePos){
  1500.     /* Only change windows that are completely off-screen
  1501.        or too big. */
  1502.     fit_in_screen (&Pref->PrWindowRect, &screen);
  1503.     fit_in_screen (&Pref->LiWindowRect, &screen);
  1504.     fit_in_screen (&Pref->HiWindowRect, &screen);
  1505.     fit_in_screen (&Pref->GrWindowRect, &screen);
  1506.   }else{
  1507.     SetRect (&Pref->LiWindowRect,
  1508.              screen.left, screen.bottom - WMINSIZE,
  1509.              screen.left + WNORMWIDTH, screen.bottom);
  1510.     fit_in_screen (&Pref->LiWindowRect, &screen);
  1511.     SetRect (&Pref->PrWindowRect,
  1512.              screen.left, screen.top,
  1513.              screen.left + WNORMWIDTH, Pref->LiWindowRect.top - WNDMARG);
  1514.     fit_in_screen (&Pref->PrWindowRect, &screen);
  1515.     SetRect (&Pref->HiWindowRect,
  1516.              Pref->PrWindowRect.right + MARGINDRAG, screen.top,
  1517.              Pref->PrWindowRect.right + MARGINDRAG + WNORMWIDTH, screen.bottom);
  1518.     if (Pref->HiWindowRect.right > screen.right) Pref->HiWindowRect.right = screen.right;
  1519.     if (Pref->HiWindowRect.right - Pref->HiWindowRect.left < WMINSIZE){
  1520.       Pref->HiWindowRect.left = Pref->HiWindowRect.right - WMINSIZE;
  1521.     }
  1522.     fit_in_screen (&Pref->HiWindowRect, &screen);
  1523.     SetRect (&Pref->GrWindowRect,
  1524.              screen.left, screen.top,
  1525.              screen.left + SIZEX + SBWIDTH -1, screen.top + SIZEY + SBWIDTH -1);
  1526.     fit_in_screen (&Pref->GrWindowRect, &screen);
  1527.   }
  1528. }
  1529.  
  1530. void SetPrefValues(ControlHandle *control)
  1531. {
  1532.     short item;
  1533.     Str255 text;
  1534.     long size[4];
  1535.     
  1536.     SetCtlValue(ctl(iReturn), Pref->Return);
  1537.     SetCtlValue(ctl(iEnter), 1 - Pref->Return);
  1538.     SetCtlValue(ctl(iShHistory), Pref->ShowHist);
  1539.     SetCtlValue(ctl(iAutoScroll), Pref->AutoScroll);
  1540.     SetCtlValue(ctl(iSavePos), Pref->SavePos);
  1541.     size[0] = Pref->PrMaxSize;
  1542.     size[1] = Pref->PrFlushSize;
  1543.     size[2] = Pref->HiMaxSize;
  1544.     size[3] = Pref->HiFlushSize;
  1545.     for (item = iPrMaxSize; item <= iHiFlushSize; item++) {
  1546.         NumToString(size[item - iPrMaxSize] / 1024, text);
  1547.         SetIText((Handle) ctl(item), text);
  1548.     }
  1549.     text [0] = 4;
  1550.     memcpy (&text [1], Pref->text_creator, 4);
  1551.     SetIText ((Handle) ctl (iTextCreator), text);
  1552. }
  1553.  
  1554. void SetPreferences(void)
  1555. {
  1556.     DialogPtr dialog;
  1557.     short item, i;
  1558.     long size[4];
  1559.     Handle resHandle, itemHandle;
  1560.     ControlHandle control[iLastControl - iFirstControl + 1];
  1561.     Rect r;
  1562.     Str255 text;
  1563.     
  1564.     if ((resHandle = GetResource('DLOG', rPreferences)) == nil)
  1565.         Error(eNoRessource);
  1566.     else {
  1567.         CenterRect((Rect *) *resHandle);
  1568.         dialog = GetNewDialog(rPreferences, nil, (WindowPtr) (-1));
  1569.         for (item = iFirstControl; item <= iLastControl; item ++)
  1570.             GetDItem(dialog, item, &i, &((Handle) ctl(item)), &r);
  1571.         SetPrefValues(control);
  1572.         GetDItem(dialog, iOK, &i, &itemHandle, &r);
  1573.         DoActivate(FrontWindow(), false);
  1574.         SetPort(dialog);
  1575.         PenSize(3,3);
  1576.         InsetRect(&r, -4, -4);
  1577.         ShowWindow(dialog);
  1578.         FrameRoundRect(&r, 16, 16);
  1579.         do {
  1580.             ModalDialog(nil, &item);
  1581.             switch (item) {
  1582.                 case iOK:
  1583.                     for(i = iPrMaxSize; i <= iHiFlushSize; i++) {
  1584.                         GetIText((Handle) ctl(i), text);
  1585.                         StringToNum(text, &size[i - iPrMaxSize]);
  1586.                         if ((size[i - iPrMaxSize] *= 1024) <= 0)
  1587.                             break;
  1588.                     }
  1589.                     if ((i > iHiFlushSize) && (i = iPrFlushSize) && (size[1] < size[0]) && (i = iHiFlushSize) && (size[3] < size[2])) {
  1590.                         Pref->Return = GetCtlValue(ctl(iReturn));
  1591.                         Pref->ShowHist = GetCtlValue(ctl(iShHistory));
  1592.                         Pref->AutoScroll = GetCtlValue(ctl(iAutoScroll));
  1593.                         Pref->SavePos = GetCtlValue(ctl(iSavePos));
  1594.                         Pref->PrMaxSize = size[0];
  1595.                         Pref->PrFlushSize = size[1];
  1596.                         Pref->HiMaxSize = size[2];
  1597.                         Pref->HiFlushSize = size[3];
  1598.                         GetIText ((Handle) ctl (iTextCreator), text);
  1599.                         for (i = 0; i < 4; i++){
  1600.                           if (i < text [0]){
  1601.                             Pref->text_creator [i] = text [i+1];
  1602.                           }else{
  1603.                             Pref->text_creator [i] = ' ';
  1604.                           }
  1605.                         }
  1606.                     } else {
  1607.                         itemHandle = GetResource('ALRT', rSizeAlert);
  1608.                         CenterRect((Rect *) *itemHandle);
  1609.                         StopAlert(rSizeAlert, nil);
  1610.                         SelIText(dialog, i, 0, 32767);
  1611.                         item = iCancel + 1;
  1612.                     }
  1613.                     break;
  1614.                 case iDefault:
  1615.                     SetDefaultPrefs ();
  1616.                     SetPrefValues(control);
  1617.                     break;
  1618.                 case iReturn:
  1619.                 case iEnter:
  1620.                     SetCtlValue(ctl(iReturn), (item == iReturn));
  1621.                     SetCtlValue(ctl(iEnter), (item == iEnter));
  1622.                     break;
  1623.                 case iShHistory:
  1624.                     SetCtlValue(ctl(iShHistory), 1 - GetCtlValue(ctl(iShHistory)));
  1625.                     break;
  1626.                 case iAutoScroll:
  1627.                     SetCtlValue(ctl(iAutoScroll), 1 - GetCtlValue(ctl(iAutoScroll)));
  1628.                     break;
  1629.                 case iSavePos:
  1630.                     SetCtlValue(ctl(iSavePos), 1 - GetCtlValue(ctl(iSavePos)));
  1631.                     break;
  1632.                 default:
  1633.                     break;
  1634.             }
  1635.         } while (item > iCancel);
  1636.         if (item == iOK)
  1637.             UpdatePreferences();
  1638.         DisposeDialog(dialog);
  1639.         ReleaseResource(resHandle);
  1640.     }
  1641. }
  1642.  
  1643. void UpdatePreferences(void)
  1644. {
  1645.   ChangedResource (RecoverHandle ((Ptr) Pref));
  1646. }
  1647.  
  1648. void CenterRect(Rect *r)
  1649. {
  1650.     short d;
  1651.     Rect *bounds;
  1652.     
  1653.     bounds = &qd.screenBits.bounds;
  1654.     d = r->right - r->left;
  1655.     r->left = bounds->left + (bounds->right - bounds->left - d) / 2;
  1656.     r->right = r->left + d;
  1657.     d = r->bottom - r->top;
  1658.     r->top = bounds->top + (bounds->bottom - bounds->top - d) / 3;
  1659.     r->bottom = r->top + d;
  1660. }
  1661.  
  1662. void AdjustScrollBars(dataPeek doc)
  1663. {
  1664.     TEPtr te;
  1665.     textPtr t;
  1666.     short max, value, scale;
  1667.     long x;
  1668.     
  1669.     switch (WindowType((WindowPtr) doc)) {
  1670.         case tInput:
  1671.             te = *((TEHandle) doc->h);
  1672.             max = te->nLines - (te->viewRect.bottom - te->viewRect.top) / te->lineHeight;
  1673.             max += (te->teLength) && (*(*te->hText + te->teLength - 1) == '\n');
  1674.             value = (te->viewRect.top - te->destRect.top) / te->lineHeight;
  1675.             SetScrollBar(doc->vSBar, max, value);
  1676.             te = *((TEHandle) doc->h);                                    /* le TERecord peut avoir change de place...    */
  1677.             max = TEWSIZE - (te->viewRect.right - te->viewRect.left + CHARWIDTH - 1) / CHARWIDTH;
  1678.             value = (te->viewRect.left - te->destRect.left) / CHARWIDTH;
  1679.             break;
  1680.         case tOutput:
  1681.         case tHistory:
  1682.             t = *((textHandle) doc->h);
  1683.             x = t->nLines - (t->viewRect.bottom - t->viewRect.top) / t->lineHeight;
  1684.             scale = 1 + x / MAXSHORT;
  1685.             max = x / scale;
  1686.             value = (t->viewRect.top - t->destRect.top) / t->lineHeight / scale;
  1687.             SetScrollBar(doc->vSBar, max, value);
  1688.             t = *((textHandle) doc->h);
  1689.             max = (t->destRect.right - t->destRect.left - t->viewRect.right + t->viewRect.left + t->width - 1) / t->width;
  1690.             value = (t->viewRect.left - t->destRect.left) / t->width;
  1691.             break;
  1692.         case tGraphic:
  1693.             max = gp->destRect.bottom - gp->destRect.top - gp->viewRect.bottom + gp->viewRect.top;
  1694.             value = gp->viewRect.top - gp->destRect.top;
  1695.             SetScrollBar(doc->vSBar, max, value);
  1696.             max = gp->destRect.right - gp->destRect.left - gp->viewRect.right + gp->viewRect.left;
  1697.             value = gp->viewRect.left - gp->destRect.left;
  1698.     }
  1699.     SetScrollBar(doc->hSBar, max, value);
  1700. }
  1701.  
  1702. void SetScrollBar(ControlHandle control, short max, short value)
  1703. {
  1704.     unsigned char state;
  1705.     
  1706.     if (max < value)
  1707.         max = value;
  1708.     if ((max != GetCtlMax(control)) || (value != GetCtlValue(control))) {
  1709.         state = (*control)->contrlVis;
  1710.         (*control)->contrlVis = inVisible;                            /* empeche SetCtl... de dessiner la scroll bar    */
  1711.         SetCtlMax(control, max);                                    /* pour pouvoir le faire seulement sur demande    */
  1712.         SetCtlValue(control, value);                                /* (ca sert pour DoGrowWindow...)                */
  1713.         if (state == Visible)
  1714.             ShowControl(control);
  1715.     }
  1716. }
  1717.  
  1718. void draw_grow_icon (WindowPtr window)
  1719. {
  1720.   PenState saved_pen;
  1721.  
  1722.   SetPort (window);
  1723.   GetPenState (&saved_pen);
  1724.   PenNormal ();
  1725.   DrawGrowIcon (window);
  1726.   SetPenState (&saved_pen);
  1727. }
  1728.  
  1729. void DoActivate(WindowPtr window, Boolean isActive)
  1730. {
  1731.     dataPeek doc;
  1732.     Rect r;
  1733.     TEHandle te;
  1734.     textHandle t;
  1735.     RgnHandle clipRgn, tempRgn;
  1736.     
  1737.     doc = (dataPeek) window;
  1738.     if (isActive) {
  1739.         SetPort(window);
  1740.         if (isTextWindow(window)) {
  1741.             clipRgn = NewRgn();
  1742.             tempRgn = NewRgn();
  1743.             GetClip(clipRgn);
  1744.             CopyRgn(((WindowPeek) window)->updateRgn, tempRgn);
  1745.             OffsetRgn(tempRgn, window->portBits.bounds.left, window->portBits.bounds.top);
  1746.             DiffRgn(clipRgn, tempRgn, tempRgn);
  1747.             SetClip(tempRgn);
  1748.             DisposeRgn(tempRgn);
  1749.             t = (textHandle) doc->h;
  1750.             if ((*t)->selStart < (*t)->selEnd)
  1751.                 InvertText(t, (*t)->selStart, (*t)->selEnd);
  1752.             SetClip(clipRgn);
  1753.             DisposeRgn(clipRgn);
  1754.         }
  1755.         if (isTEWindow(window)) {
  1756.             TEActivate(te = (TEHandle) doc->h);
  1757.             TEFromScrap();
  1758.         }
  1759.         (*doc->vSBar)->contrlVis = Visible;
  1760.         (*doc->hSBar)->contrlVis = Visible;
  1761.         r = (*doc->vSBar)->contrlRect;
  1762.         InvalRect(&r);                            /* un updateEvt redessinera les controles                */
  1763.         r = window->portRect;
  1764.         r.top = r.bottom - SBWIDTH + 1;
  1765.         InvalRect(&r);
  1766.     } else {
  1767.         HideControl(doc->vSBar);
  1768.         HideControl(doc->hSBar);
  1769.         draw_grow_icon(window);
  1770.         SetPort(window);
  1771.         ValidRect(&(*doc->vSBar)->contrlRect);    /* permet d'eviter l'updateEvt genere par HideControl    */
  1772.         ValidRect(&(*doc->hSBar)->contrlRect);
  1773.         if (isTEWindow(window)) {
  1774.             if (TEGetScrapLen() > 0)
  1775.                 if (ZeroScrap() != noErr)
  1776.                     Error(eNoScrap);
  1777.                 else
  1778.                     if (TEToScrap() != noErr)
  1779.                         Error(eNoScrapPut);
  1780.             TEDeactivate((TEHandle) doc->h);
  1781.         }
  1782.         if (isTextWindow(window)) {
  1783.             t = (textHandle) doc->h;
  1784.             if ((*t)->selStart < (*t)->selEnd)
  1785.                 InvertText(t, (*t)->selStart, (*t)->selEnd);
  1786.         }
  1787.     }
  1788. }
  1789.  
  1790. void copy_bits (const BitMap *srcBits, const BitMap *dstBits, const Rect *srcRect,
  1791.                const Rect *dstRect, short mode, RgnHandle maskRgn)
  1792. {
  1793.   if (color_qd){
  1794.     RGBColor fore, back;
  1795.     RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
  1796.     RGBColor black = {0, 0, 0};
  1797.     
  1798.     GetForeColor (&fore);
  1799.     GetBackColor (&back);
  1800.     RGBForeColor (&black);
  1801.     RGBBackColor (&white);
  1802.     CopyBits (srcBits, dstBits, srcRect, dstRect, mode, maskRgn);
  1803.     RGBForeColor (&fore);
  1804.     RGBBackColor (&back);
  1805.   }else{
  1806.     CopyBits (srcBits, dstBits, srcRect, dstRect, mode, maskRgn);
  1807.   }
  1808. }
  1809.  
  1810. void copy_mask (const BitMap *srcBits, const BitMap *maskBits, const BitMap *dstBits,
  1811.                 const Rect *srcRect, const Rect *maskRect, const Rect *dstRect)
  1812. {
  1813.   if (color_qd){
  1814.     RGBColor fore, back;
  1815.     RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
  1816.     RGBColor black = {0, 0, 0};
  1817.     
  1818.     GetForeColor (&fore);
  1819.     GetBackColor (&back);
  1820.     RGBForeColor (&black);
  1821.     RGBBackColor (&white);
  1822.     CopyMask (srcBits, maskBits, dstBits, srcRect, maskRect, dstRect);
  1823.     RGBForeColor (&fore);
  1824.     RGBBackColor (&back);
  1825.   }else{
  1826.     CopyMask (srcBits, maskBits, dstBits, srcRect, maskRect, dstRect);
  1827.   }
  1828. }
  1829.  
  1830. void DoUpdate(WindowPtr window)
  1831. {
  1832.     Rect r;
  1833.     
  1834.     BeginUpdate(window);
  1835.     SetPort(window);
  1836.     EraseRect(&window->portRect);
  1837.     UpdateControls(window, window->visRgn);
  1838.     draw_grow_icon(window);
  1839.     r = window->portRect;
  1840.     r.right -= SBWIDTH - 1;
  1841.     r.bottom -= SBWIDTH - 1;
  1842.     if (SectRect(&r, &(*window->visRgn)->rgnBBox, &r))
  1843.         switch (WindowType(window)) {
  1844.             case tOutput:
  1845.             case tHistory:
  1846.                 TextUpdate((textHandle) ((dataPeek) window)->h);
  1847.                 break;
  1848.             case tInput:
  1849.                 TEUpdate(&r, (TEHandle) ((dataPeek) window)->h);
  1850.                 break;
  1851.             case tGraphic:
  1852.               { Rect offRect = r;
  1853.                 
  1854.                 OffsetRect (&offRect, gp->viewRect.left - gp->destRect.left,
  1855.                             gp->viewRect.top - gp->destRect.top);
  1856.                 copy_bits (&CAMLOffScreen->portBits, &window->portBits,
  1857.                            &offRect, &r, srcCopy, nil);
  1858.               }
  1859.             }
  1860.     EndUpdate(window);
  1861. }
  1862.  
  1863. void TextUpdate(textHandle t)    /* la procedure suppose que SetPort a deja ete fait...    */
  1864. {
  1865.     RgnHandle clipRgn, viewRgn;
  1866.     Rect r;
  1867.     long i;
  1868.     short nlines, nchars, firstChar, line, len;
  1869.     char *text;
  1870.     GrafPtr port;
  1871.     
  1872.     clipRgn = NewRgn();
  1873.     viewRgn = NewRgn();
  1874.     GetClip(clipRgn);
  1875.     r = (*t)->viewRect;
  1876.     RectRgn(viewRgn, &r);
  1877.     SectRgn(clipRgn, viewRgn, viewRgn);            /* pour ne pas ecrire sur la scroll bar par exemple    */
  1878.     SetClip(viewRgn);
  1879.     DisposeRgn(viewRgn);
  1880.     HLock((*t)->hText);
  1881.     nlines = (r.bottom - r.top) / (*t)->lineHeight;
  1882.     nchars = (r.right - r.left + (*t)->width - 1) / (*t)->width;
  1883.     firstChar = (r.left - (*t)->destRect.left) / (*t)->width;
  1884.     for (i = (*t)->firstLine, line = 0; (i < (*t)->teLength) && (line < nlines); i++, line++) {
  1885.         for (text = *(*t)->hText + i, len = 0; (i < (*t)->teLength) && (*(text + len) != '\n'); i++, len++)
  1886.             ;
  1887.         if (len > firstChar) {
  1888.             len -= firstChar;
  1889.             if (len > nchars)
  1890.                 len = nchars;
  1891.             MoveTo(r.left, r.top + line * (*t)->lineHeight + (*t)->ascent);
  1892.             DrawText(text, firstChar, len);
  1893.         }
  1894.     }
  1895.     HUnlock((*t)->hText);
  1896.     GetPort(&port);
  1897.     if ((port == FrontWindow()) && inForeground)
  1898.         InvertText(t, (*t)->selStart, (*t)->selEnd);
  1899.     SetClip(clipRgn);
  1900.     DisposeRgn(clipRgn);
  1901. }
  1902.  
  1903. void InvertText(textHandle t, long start, long end)
  1904. {
  1905.     long i;
  1906.     short nlines, firstChar, nchars, line, n, x;
  1907.     char *text;
  1908.     Rect r;
  1909.     RgnHandle selection;
  1910.     
  1911.     if ((i = start) > end) {
  1912.         start = end;
  1913.         end = i;
  1914.     }
  1915.     if ((end > (i = (*t)->firstLine)) && (start < (*t)->teLength)) {
  1916.         if (start < i)
  1917.             start = i;
  1918.         nlines = ((*t)->viewRect.bottom - (*t)->viewRect.top) / (*t)->lineHeight;
  1919.         firstChar = ((*t)->viewRect.left - (*t)->destRect.left) / (*t)->width;
  1920.         nchars = ((*t)->viewRect.right - (*t)->viewRect.left + (*t)->width - 1) / (*t)->width;
  1921.         text = *(*t)->hText + i;
  1922.         for (line = 0, x = 0; (i < (*t)->teLength) && (i < start) && (line < nlines); i++, x++)
  1923.             if (*text++ == '\n') {
  1924.                 line++;
  1925.                 x = -1;
  1926.             }
  1927.         if (line < nlines) {
  1928.             selection = NewRgn();
  1929.             OpenRgn();
  1930.             while ((i < (*t)->teLength) && (i < end) && (line < nlines)) {
  1931.                 for (n = 0; (i < (*t)->teLength) && (i < end) && (*text != '\n'); i++, n++, text++)
  1932.                     ;
  1933.                 if ((i < (*t)->teLength) && (i < end) && (*text == '\n')) {
  1934.                     n = firstChar + nchars;
  1935.                     i++;
  1936.                     text++;
  1937.                 }
  1938.                 if (x < firstChar + nchars) {
  1939.                     if (x < firstChar) {
  1940.                         n -= firstChar - x;
  1941.                         x = firstChar;
  1942.                     }
  1943.                     if (n > 0) {
  1944.                         if (x + n > firstChar + nchars)
  1945.                             n = firstChar + nchars - x;
  1946.                         if ((r.right = (r.left = (*t)->destRect.left + x * (*t)->width) + n * (*t)->width) > (*t)->viewRect.right)
  1947.                             r.right = (*t)->viewRect.right;
  1948.                         r.bottom = (r.top = (*t)->viewRect.top + line * (*t)->lineHeight) + (*t)->lineHeight;
  1949.                         FrameRect(&r);
  1950.                     }
  1951.                 }
  1952.                 x = 0;
  1953.                 line ++;
  1954.             }
  1955.             CloseRgn(selection);
  1956.             InvertRgn(selection);
  1957.             DisposeRgn(selection);
  1958.         }
  1959.     }
  1960. }
  1961.  
  1962. void FlushText(WindowPtr window)
  1963. {
  1964.     textPtr t;
  1965.     char *src, *text;
  1966.     long delta, i, j, *buffer;
  1967.     Boolean redraw = false;
  1968.     Rect r;
  1969.  
  1970.     t = *((textHandle) ((dataPeek) window)->h);
  1971.     delta = (window == CAMLPrinter) ? Pref->PrFlushSize : Pref->HiFlushSize;
  1972.     if (delta > t->teLength)
  1973.         delta = t->teLength;
  1974.     if (window == CAMLHistory) {                            /* aligne delta sur un buffer, et les decale        */
  1975.         buffer = *t->buffer;
  1976.         if (delta > buffer[buffer[1]])
  1977.             delta = buffer[buffer[1]];
  1978.         for(i = 2; buffer[i] < delta; i++)
  1979.             ;
  1980.         delta = buffer[i];
  1981.         buffer[1] -= (i - 2);
  1982.         buffer[0] -= (i - 2);
  1983.         for(j = 2; j <= buffer[0]; i++, j++)
  1984.             buffer[j] = buffer[i] - delta;
  1985.         indexBuffer -= (i - 2);
  1986.         if (indexBuffer < 2) indexBuffer = buffer [0];
  1987.     }
  1988.     src = (text = *t->hText) + delta;
  1989.     for(i = (t->teLength -= delta), j = 1; i > 0; i--) {    /* deplace le texte en comptant le nombre de lignes    */
  1990.         *text = *src++;
  1991.         if (*text++ == '\n')
  1992.             j++;
  1993.     }
  1994.     if ((t->teLength > 0) && (*--text == '\n'))
  1995.         j--;
  1996.     if ((t->selStart -= delta) < 0)                            /* remise a jour de differentes variables            */
  1997.         t->selStart = 0;
  1998.     if ((t->selEnd -= delta) < 0)
  1999.         t->selEnd = 0;
  2000.     if ((t->firstLine -= delta) < 0) {
  2001.         t->firstLine = 0;
  2002.         redraw = true;
  2003.     }
  2004.     if ((t->destRect.top += (t->nLines - j) * t->lineHeight) > t->viewRect.top) {
  2005.         t->destRect.top = t->viewRect.top;
  2006.         t->firstLine = 0;
  2007.         redraw = true;
  2008.     }
  2009.     t->nLines = j;
  2010.     if (redraw) {
  2011.         r = t->viewRect;
  2012.         EraseRect(&r);
  2013.         TextUpdate((textHandle) ((dataPeek) window)->h);
  2014.     }
  2015.     AdjustScrollBars((dataPeek) window);
  2016. }
  2017.  
  2018. void VScrollText(textHandle t, long dv)
  2019. {
  2020.     long i, firstLine, line;
  2021.     short nlines;
  2022.     RgnHandle updateRgn;
  2023.     Rect r;
  2024.     char *text;
  2025.     
  2026.     (*t)->destRect.top += dv * (*t)->lineHeight;
  2027.     r = (*t)->viewRect;
  2028.     nlines = (r.bottom - r.top) / (*t)->lineHeight;
  2029.     if (dv < 0) {
  2030.         for (i = (*t)->firstLine, text = *(*t)->hText, line = dv; (line < 0) && (i < (*t)->teLength); line++, i++)
  2031.             while ((i < (*t)->teLength) && (*(text + i) != '\n'))
  2032.                 i++;
  2033.         (*t)->firstLine = i;
  2034.         if (dv <= -nlines) {
  2035.             EraseRect(&r);
  2036.             TextUpdate(t);
  2037.         } else {
  2038.             updateRgn = NewRgn();
  2039.             ScrollRect(&r, 0, dv * (*t)->lineHeight, updateRgn);
  2040.             if ((*updateRgn)->rgnBBox.top - r.bottom < dv * (*t)->lineHeight)
  2041.                 dv = -((r.bottom - (*updateRgn)->rgnBBox.top) / (*t)->lineHeight + 1);
  2042.             for (firstLine = i, text = *(*t)->hText, line = nlines + dv; (i < (*t)->teLength) && (line > 0); i++)
  2043.                     if (*(text + i) == '\n')
  2044.                         line--;
  2045.             if (i < (*t)->teLength) {
  2046.                 (*t)->firstLine = i;
  2047.                 (*t)->viewRect.top += (nlines + dv) * (*t)->lineHeight;
  2048.                 TextUpdate(t);
  2049.                 (*t)->viewRect.top = r.top;
  2050.                 (*t)->firstLine = firstLine;
  2051.             }
  2052.             DisposeRgn(updateRgn);
  2053.         }
  2054.     } else
  2055.         if ((dv > 0) && ((*t)->firstLine > 0)) {
  2056.             for (i = (*t)->firstLine - 1, text = *(*t)->hText, line = dv; (line >= 0) && (i >= 0); line--, i--)
  2057.                 while ((i >= 0) && (*(text + i) != '\n'))
  2058.                     i--;
  2059.             (*t)->firstLine = i + 2;
  2060.             if (dv >= nlines) {
  2061.                 EraseRect(&r);
  2062.                 TextUpdate(t);
  2063.             } else {
  2064.                 updateRgn = NewRgn();
  2065.                 ScrollRect(&r, 0, dv * (*t)->lineHeight, updateRgn);
  2066.                 DisposeRgn(updateRgn);
  2067.                 (*t)->viewRect.bottom = r.top + dv * (*t)->lineHeight;
  2068.                 TextUpdate(t);
  2069.                 (*t)->viewRect.bottom = r.bottom;
  2070.             }
  2071.         }
  2072. }
  2073.  
  2074. void HScrollText(textHandle t, short dh)
  2075. {
  2076.     Rect r;
  2077.     short nchars, bound;
  2078.     RgnHandle updateRgn, clipRgn;
  2079.     
  2080.     if (dh != 0) {
  2081.         (*t)->destRect.left += dh * (*t)->width;
  2082.         (*t)->destRect.right += dh * (*t)->width;
  2083.         r = (*t)->viewRect;
  2084.         nchars = (r.right - r.left) / (*t)->width;
  2085.         if ((dh >= nchars) || (dh <= -nchars)) {
  2086.             EraseRect(&r);
  2087.             TextUpdate(t);
  2088.         } else {
  2089.             updateRgn = NewRgn();
  2090.             ScrollRect(&r, dh * (*t)->width, 0, updateRgn);
  2091.             clipRgn = NewRgn();
  2092.             GetClip(clipRgn);
  2093.             SetClip(updateRgn);
  2094.             if (dh > 0) {
  2095.                 (*t)->viewRect.right = r.left + dh * (*t)->width;
  2096.                 if ((*t)->viewRect.right < (bound = (*updateRgn)->rgnBBox.right))
  2097.                     (*t)->viewRect.right = bound;
  2098.             } else {
  2099.                 (*t)->viewRect.left += (nchars + dh) * (*t)->width;
  2100.                 if ((*t)->viewRect.left > (bound = (*updateRgn)->rgnBBox.left))
  2101.                     (*t)->viewRect.left = r.left + (bound - r.left) / (*t)->width * (*t)->width;
  2102.             }
  2103.             DisposeRgn(updateRgn);
  2104.             TextUpdate(t);
  2105.             (*t)->viewRect = r;
  2106.             SetClip(clipRgn);
  2107.             DisposeRgn(clipRgn);
  2108.         }
  2109.     }
  2110. }
  2111.  
  2112. void ScrollGraph(dataPeek doc, short dh, short dv)
  2113. {
  2114.     RgnHandle updateRgn;
  2115.     Rect r, offRect;
  2116.     
  2117.     updateRgn = NewRgn();
  2118.     ScrollRect(&gp->viewRect, dh, dv, updateRgn);
  2119.     OffsetRect(&gp->destRect, dh, dv);
  2120.     SectRect(&gp->viewRect, &(*updateRgn)->rgnBBox, &r);
  2121.     offRect = r;
  2122.     OffsetRect(&offRect, gp->viewRect.left - gp->destRect.left, gp->viewRect.top - gp->destRect.top);
  2123.     SetPort (CAMLGraph);
  2124.     copy_bits (&CAMLOffScreen->portBits, &CAMLGraph->portBits, &offRect, &r, srcCopy, nil);
  2125.      DisposeRgn(updateRgn);
  2126.     AdjustScrollBars(doc);
  2127. }
  2128.  
  2129. void DoGrowWindow(WindowPtr window, EventRecord *event)
  2130. {
  2131.     Rect r, *destRect;
  2132.     long newSize;
  2133.     short bound;
  2134.     
  2135.     if (((WindowPeek) window)->windowKind == userKind) {
  2136.         if (isGraphWindow(window)) {
  2137.             r.right = gp->destRect.right - gp->destRect.left + SBWIDTH;
  2138.             r.bottom = gp->destRect.bottom - gp->destRect.top + SBWIDTH;
  2139.         } else {
  2140.             r.right = qd.screenBits.bounds.right;
  2141.             r.bottom = qd.screenBits.bounds.bottom;
  2142.         }
  2143.         r.left = WMINSIZE;
  2144.         r.top = WMINSIZE;
  2145.         if (newSize = GrowWindow(window, event->where, &r)) {
  2146.             SetPort(window);
  2147.             InvalRect(&window->portRect);                                    /* on redessine tout !                            */
  2148.             SizeWindow(window, LoWord(newSize), HiWord(newSize), true);        /* la fenetre sera dessinee via un updateEvt    */
  2149.             if (isGraphWindow(window)) {
  2150.                 destRect = &((graphPeek) CAMLOffScreen)->destRect;
  2151.                 bound = window->portRect.right - SBWIDTH + 1;
  2152.                 if (bound > destRect->right)
  2153.                     OffsetRect(destRect, bound - destRect->right, 0);
  2154.                 bound = window->portRect.bottom - SBWIDTH + 1;
  2155.                 if (bound > destRect->bottom)
  2156.                     OffsetRect(destRect, 0, bound - destRect->bottom);
  2157.                 ClipRect(&CAMLGraph->portRect);
  2158.             }
  2159.             FixViewRect(window);
  2160.             (*((dataPeek) window)->vSBar)->contrlVis = inVisible;            /* pour que AdjustScrollBars ne redessine pas    */
  2161.             (*((dataPeek) window)->hSBar)->contrlVis = inVisible;            /* les controles, ce sera fait par UpdtControls    */
  2162.             AdjustScrollBars((dataPeek) window);
  2163.             FixScrollBar((dataPeek) window);                                /* remet les controles a l'etat visible            */
  2164.         }
  2165.     }
  2166. }
  2167.  
  2168. Boolean DoNew(short index, Rect *boundsRect)
  2169. {
  2170.     Ptr storage;
  2171.     WindowPtr window;
  2172.     Str255 title;
  2173.     dataPeek doc;
  2174.     Boolean goAwayFlag;
  2175.     Rect r;
  2176.  
  2177.     storage = NewPtr(sizeof(dataRecord));
  2178.     if (storage != nil) {
  2179.         GetIndString(title, rWTitle, index);
  2180.         goAwayFlag = ((index == tHistory) || (index == tGraphic));
  2181.         if (color_qd && index == tGraphic){
  2182.           window = (WindowPtr) NewCWindow (storage, boundsRect, title, false, zoomDocProc, nil, goAwayFlag, 0);
  2183.         }else{
  2184.           window = NewWindow(storage, boundsRect, title, false, zoomDocProc, nil, goAwayFlag, 0);
  2185.         }
  2186.         doc = (dataPeek) window;
  2187.         SetRect(&r, 0, 0, 16, 50);
  2188.         doc->vSBar = NewControl(window, &r, "\p", false, 0, 0, 0, scrollBarProc, 0);
  2189.         doc->hSBar = NewControl(window, &r, "\p", false, 0, 0, 0, scrollBarProc, 0);
  2190.         doc->type = index;
  2191.         doc->h = nil;
  2192.         doc->prevWindow = nil;
  2193.         doc->nextWindow = WList;
  2194.         if (WList != nil)
  2195.             WList->prevWindow = doc;
  2196.         WList = doc;
  2197.         SetPort(window);
  2198.         SetOrigin(0,0);
  2199.         TextFont(monaco);                            /* la largeur des caractères est constante dans cette font    */
  2200.         TextSize(FONTSIZE);
  2201.         FixScrollBar(doc);
  2202.         (*doc->vSBar)->contrlVis = inVisible;        /* ShowWindow genere un updateEvt, qui prendra en charge le    */
  2203.         (*doc->hSBar)->contrlVis = inVisible;        /* remplissage de la nouvelle fenetre; il faut forcer les    */
  2204.         if (index != tHistory)                        /* scroll bars a etre redessinees par DoActivate.            */
  2205.             ShowWindow(window);
  2206.         return true;
  2207.     }
  2208.     return false;
  2209. }
  2210.  
  2211. void OpenOutput(short windowType)
  2212. {
  2213.     Rect r;
  2214.     dataPeek doc;
  2215.     FontInfo info;
  2216.     textPtr t;
  2217.     Handle temp;
  2218.     
  2219.     r = (windowType == tOutput) ? Pref->PrWindowRect : Pref->HiWindowRect;
  2220.     if (DoNew(windowType, &r)) {
  2221.         doc = WList;
  2222.         doc->h = (long) NewHandle(sizeof(textRecord));
  2223.         if (doc->h != nil) {
  2224.             temp = NewHandle(TEBLOCK);
  2225.             (*((textHandle) doc->h))->hText = temp;
  2226.             if (temp != nil) {
  2227.                 GetFontInfo(&info);
  2228.                 t = *((textHandle) doc->h);                        /* attention aux routines qui deplacent ou purgent la memoire !    */
  2229.                 t->lineHeight = info.ascent + info.descent + info.leading;
  2230.                 t->ascent = info.ascent;
  2231.                 t->width = info.widMax;
  2232.                 FixViewRect((WindowPtr) doc);
  2233.                 t->destRect.top = t->viewRect.top;
  2234.                 t->destRect.right = (t->destRect.left = t->viewRect.left);
  2235.                 t->last_line_length = 0;
  2236.                 t->selStart = 0;
  2237.                 t->selEnd = 0;
  2238.                 t->teLength = 0;
  2239.                 t->firstLine = 0;
  2240.                 t->nLines = 1;
  2241.                 AdjustScrollBars(doc);
  2242.                 if (windowType == tOutput) {
  2243.                     CAMLPrinter = (WindowPtr) doc;
  2244.                     t->buffer = nil;
  2245.                     return;
  2246.                 } else {
  2247.                     temp = NewHandle(BUFBLOCK);
  2248.                     (*((textHandle) doc->h))->buffer = (bufHandle) temp;
  2249.                     if (temp != nil) {
  2250.                         (*((bufHandle) temp))[0] = 2;
  2251.                         (*((bufHandle) temp))[1] = 2;
  2252.                         (*((bufHandle) temp))[2] = 0;
  2253.                         CAMLHistory = (WindowPtr) doc;
  2254.                         if (Pref->ShowHist)
  2255.                             ShowWindow(CAMLHistory);
  2256.                         return;
  2257.                     }
  2258.                 }
  2259.             }
  2260.         }
  2261.     }
  2262.     Error(eNoMemory);
  2263.     Pref->SavePos = false;
  2264.     Quit();
  2265. }
  2266.  
  2267. void OpenInput(void)
  2268. {
  2269.     dataPeek doc;
  2270.     Rect destRect;
  2271.     TEHandle te;
  2272.     
  2273.     if (DoNew(tInput, &Pref->LiWindowRect)) {
  2274.         doc = WList;
  2275.         CAMLInput = (WindowPtr) doc;
  2276.         destRect = ((WindowPtr) doc)->portRect;
  2277.         doc->h = (long) TENew(&destRect, &destRect);
  2278.         if (doc->h != nil) {
  2279.             te = (TEHandle) doc->h;
  2280.             TEAutoView(true, te);
  2281.             (*te)->crOnly = WRAP;
  2282.             oldClikLoop = (*te)->clikLoop;
  2283.             (*te)->clikLoop = (ClikLoopProcPtr) AsmClikLoop;
  2284.             FixViewRect((WindowPtr) doc);
  2285.             destRect = (*te)->viewRect;
  2286.             destRect.right = destRect.left + TEWSIZE * CHARWIDTH;
  2287.             (*te)->destRect = destRect;
  2288.             AdjustScrollBars(doc);
  2289.             return;
  2290.         } else
  2291.             Error(eNoTextEdit);
  2292.     } else
  2293.         Error(eNoMemory);
  2294.     Pref->SavePos = false;
  2295.     Quit();
  2296. }
  2297.  
  2298. Boolean OpenGraph(void)
  2299. {
  2300.     dataPeek doc;
  2301.     Rect r;
  2302.     
  2303.     if (DoNew(tGraphic, &Pref->GrWindowRect)) {
  2304.         graph_event_head = graph_event_tail = 0;
  2305.         CAMLGraph = (WindowPtr) (doc = WList);
  2306.         doc->h = (long) NewPtr(sizeof(graphRecord));
  2307.         if (doc->h != nil) {
  2308.             FixViewRect(CAMLGraph);
  2309.             CAMLOffScreen = (GrafPtr) doc->h;
  2310.             r = gp->viewRect;
  2311.             r.right = r.left + SIZEX;
  2312.             r.bottom = r.top + SIZEY;
  2313.             if (color_qd){
  2314.               GDHandle the_max_device, old_device;
  2315.               CTabHandle color_map;
  2316.               Rect wide_open = {-32000, -32000, 32000, 32000};
  2317.               CGrafPtr color_off_screen = (CGrafPtr) CAMLOffScreen;
  2318.               long off_row_bytes;
  2319.               
  2320.               the_max_device = GetMaxDevice (&wide_open);
  2321.               old_device = GetGDevice ();
  2322.               CAMLGDevice = NewGDevice (0, 0);
  2323.               max_depth = (*(*the_max_device)->gdPMap)->pixelSize;
  2324.               **(*CAMLGDevice)->gdPMap = **(*the_max_device)->gdPMap;
  2325.               off_row_bytes = (max_depth * (r.right - r.left) + 31) / 32 * 4;
  2326.               (*(*CAMLGDevice)->gdPMap)->rowBytes = off_row_bytes + 0x8000;
  2327.               (*(*CAMLGDevice)->gdPMap)->baseAddr = NewPtr (off_row_bytes * (long) (r.bottom - r.top));
  2328.               if ((*(*CAMLGDevice)->gdPMap)->baseAddr == nil){
  2329.                 DoClose (CAMLGraph);
  2330.                 return false;
  2331.               }
  2332.               (*(*CAMLGDevice)->gdPMap)->bounds = r;
  2333.               color_map = (*(*the_max_device)->gdPMap)->pmTable;
  2334.               if (HandToHand ((Handle *) &color_map) != noErr){
  2335.                 DoClose (CAMLGraph);
  2336.                 return false;
  2337.               }
  2338.               (*(*CAMLGDevice)->gdPMap)->pmTable = color_map;
  2339.               SetGDevice (CAMLGDevice);
  2340.               MakeITable (nil, nil, (*the_max_device)->gdResPref);
  2341.               if (QDError () != noErr){
  2342.                 SetGDevice (old_device);
  2343.                 DoClose (CAMLGraph);
  2344.                 return false;
  2345.               }
  2346.               OpenCPort (color_off_screen);
  2347.               SetGDevice (old_device);
  2348.               SetPalette (CAMLGraph, nil, 1);
  2349.             }else{
  2350.               max_depth = 1;
  2351.               OpenPort(CAMLOffScreen);
  2352.               CAMLOffScreen->portBits.rowBytes = (r.right - r.left + 31) / 32 * 4;
  2353.               CAMLOffScreen->portBits.baseAddr = NewPtr(CAMLOffScreen->portBits.rowBytes * (long) (r.bottom - r.top));
  2354.               CAMLOffScreen->portBits.bounds = r;
  2355.               if (CAMLOffScreen->portBits.baseAddr == nil){
  2356.                 DoClose (CAMLGraph);
  2357.                 return false;
  2358.               }
  2359.             }
  2360.             CAMLOffScreen->portRect = r;
  2361.             EraseRect(&r);
  2362.             r.bottom = gp->viewRect.bottom;
  2363.             r.top = r.bottom - SIZEY;
  2364.             gp->destRect = r;
  2365.             gp->destRectZoom = r;
  2366.             r = qd.screenBits.bounds;
  2367.             r.top += GetMBarHeight() + SBWIDTH;
  2368.             InsetRect(&r, MARGINDRAG, MARGINDRAG);
  2369.             if (r.right - r.left > SIZEX + SBWIDTH - 1)
  2370.                 r.left = r.right - SIZEX - SBWIDTH + 1;
  2371.             if (r.bottom - r.top > SIZEY + SBWIDTH - 1)
  2372.                 r.top = r.bottom - SIZEY - SBWIDTH + 1;
  2373.             (*((WStateDataHandle) ((WindowPeek) CAMLGraph)->dataHandle))->stdState = r;
  2374.             TextFont(monaco);
  2375.             TextSize(FONTSIZE);
  2376.             SetPort(CAMLGraph);
  2377.             AdjustScrollBars(doc);
  2378.             EnableItem(GetMHandle(mCaml), iShowGraph);
  2379.             SelectWindow(CAMLGraph);
  2380.             return true;
  2381.         }
  2382.         DoClose(CAMLGraph);
  2383.     }
  2384.     return false;
  2385. }
  2386.  
  2387. void DoClose(WindowPtr window)
  2388. {
  2389.     dataPeek doc;
  2390.     
  2391.     doc = (dataPeek) window;
  2392.     if (doc->h != nil)
  2393.         switch (WindowType(window)) {
  2394.             case tInput:
  2395.                 TEDispose((TEHandle) doc->h);
  2396.                 break;
  2397.             case tOutput:
  2398.             case tHistory:
  2399.                 if ((*((textHandle) doc->h))->hText != nil)
  2400.                     DisposeHandle((*((textHandle) doc->h))->hText);
  2401.                 if ((window == CAMLHistory) && ((*((textHandle) doc->h))->buffer != nil))
  2402.                     DisposeHandle((Handle) (*((textHandle) doc->h))->buffer);
  2403.                 DisposeHandle((Handle) doc->h);
  2404.                 break;
  2405.             case tGraphic:
  2406.                 GetWindowPos(CAMLGraph, &Pref->GrWindowRect);
  2407.                 if (color_qd){
  2408.                   if ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr != nil)
  2409.                     DisposePtr ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr);
  2410.                   CloseCPort ((CGrafPtr) CAMLOffScreen);
  2411.                   DisposGDevice (CAMLGDevice);
  2412.                   CAMLGDevice = nil;
  2413.                 }else{
  2414.                   if (CAMLOffScreen->portBits.baseAddr != nil)
  2415.                     DisposePtr(CAMLOffScreen->portBits.baseAddr);
  2416.                   ClosePort(CAMLOffScreen);
  2417.                 }
  2418.                 DisposePtr((Ptr) CAMLOffScreen);
  2419.                 DisableItem(GetMHandle(mCaml), iShowGraph);
  2420.                 CAMLGraph = nil;
  2421.                 CAMLOffScreen = nil;
  2422.         }
  2423.     CloseWindow(window);
  2424.     if (doc->prevWindow == nil)
  2425.         WList = doc->nextWindow;
  2426.     else
  2427.         (doc->prevWindow)->nextWindow = doc->nextWindow;
  2428.     if (doc->nextWindow != nil)
  2429.         (doc->nextWindow)->prevWindow = doc->prevWindow;
  2430.     DisposePtr((Ptr) window);
  2431. }
  2432.  
  2433. pascal ProcPtr GetOldClikLoop(void)
  2434. {
  2435.     return (ProcPtr) oldClikLoop;
  2436. }
  2437.  
  2438. pascal void ClikLoop(void)
  2439. {
  2440.     WindowPtr window;
  2441.     RgnHandle clipRgn;
  2442.     
  2443.     window = FrontWindow();
  2444.     clipRgn = NewRgn();
  2445.     GetClip(clipRgn);
  2446.     ClipRect(&window->portRect);
  2447.     AdjustScrollBars((dataPeek) window);
  2448.     SetClip(clipRgn);
  2449.     DisposeRgn(clipRgn);
  2450. }
  2451.  
  2452. void FixViewRect(WindowPtr window)
  2453. {
  2454.     Rect viewRect;
  2455.     long h;
  2456.     short height;
  2457.     
  2458.     if (isGraphWindow(window)) {
  2459.         viewRect = window->portRect;
  2460.         viewRect.right -= SBWIDTH - 1;
  2461.         viewRect.bottom -= SBWIDTH - 1;
  2462.         ((graphPeek) ((dataPeek) window)->h)->viewRect = viewRect;
  2463.     } else {
  2464.         viewRect.top = TXTMARG;
  2465.         viewRect.left = TXTMARG;
  2466.         viewRect.bottom = window->portRect.bottom - SBWIDTH + 1 - TXTMARG;
  2467.         viewRect.right = window->portRect.right - SBWIDTH + 1;
  2468.         if (isTEWindow(window))
  2469.             viewRect.right -= 2;
  2470.         h = ((dataPeek) window)->h;
  2471.         height = (isTEWindow(window)) ? (*((TEHandle) h))->lineHeight : (*((textHandle) h))->lineHeight;
  2472.         viewRect.bottom = viewRect.top + ((viewRect.bottom - viewRect.top) / height) * height;
  2473.         if (isTEWindow(window))
  2474.             (*((TEHandle) h))->viewRect = viewRect;
  2475.         else
  2476.             (*((textHandle) h))->viewRect = viewRect;
  2477.     }
  2478. }
  2479.  
  2480. void FixScrollBar(dataPeek doc)
  2481. {
  2482.     Rect r;
  2483.     
  2484.     r = ((WindowPtr) doc)->portRect;
  2485.     (*doc->vSBar)->contrlVis = inVisible;
  2486.     (*doc->hSBar)->contrlVis = inVisible;
  2487.     SizeControl(doc->vSBar, SBWIDTH, r.bottom - r.top - SBWIDTH + 3);
  2488.     MoveControl(doc->vSBar, r.right - SBWIDTH + 1, -1);
  2489.     SizeControl(doc->hSBar, r.right - r.left - SBWIDTH + 3, SBWIDTH);
  2490.     MoveControl(doc->hSBar, -1, r.bottom - SBWIDTH + 1);
  2491.     (*doc->vSBar)->contrlVis = Visible;
  2492.     (*doc->hSBar)->contrlVis = Visible;
  2493. }
  2494.  
  2495. void Error(short error)
  2496. {
  2497.     Str255 message;
  2498.     Handle h;
  2499.     
  2500.     SetCursor(&qd.arrow);
  2501.     GetIndString(message, rErrorList, error);
  2502.     ParamText(message, "\p", "\p", "\p");
  2503.     h = GetResource('ALRT', rErrorAlert);
  2504.     CenterRect((Rect *) *h);
  2505.     StopAlert(rErrorAlert, nil);
  2506.     ReleaseResource(h);
  2507. }
  2508.